Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010-2016, 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 
     29 #include <string.h>
     30 #include <sys/ioctl.h>
     31 #include <sys/prctl.h>
     32 #include <sys/eventfd.h>
     33 #include <unistd.h>
     34 #include <fcntl.h>
     35 #include "video_encoder_device_v4l2.h"
     36 #include "omx_video_encoder.h"
     37 #include <media/msm_vidc.h>
     38 #ifdef USE_ION
     39 #include <linux/msm_ion.h>
     40 #endif
     41 #include <media/msm_media_info.h>
     42 #include <cutils/properties.h>
     43 #include <media/hardware/HardwareAPI.h>
     44 
     45 #ifdef _ANDROID_
     46 #include <media/hardware/HardwareAPI.h>
     47 #include <gralloc_priv.h>
     48 #endif
     49 
     50 #include <qdMetaData.h>
     51 
     52 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
     53 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
     54 #define MAXDPB 16
     55 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
     56 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
     57 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
     58 #define MAX_PROFILE_PARAMS 6
     59 #define MPEG4_SP_START 0
     60 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
     61 #define H263_BP_START 0
     62 #define H264_BP_START 0
     63 #define H264_HP_START (H264_BP_START + 18)
     64 #define H264_MP_START (H264_BP_START + 36)
     65 #define HEVC_MAIN_START 0
     66 #define HEVC_MAIN10_START (HEVC_MAIN_START + 13)
     67 #define POLL_TIMEOUT 1000
     68 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
     69 
     70 #define SZ_4K 0x1000
     71 #define SZ_1M 0x100000
     72 
     73 /* MPEG4 profile and level table*/
     74 static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
     75     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
     76     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
     77     {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
     78     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
     79     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
     80     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
     81     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
     82     {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
     83     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
     84     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
     85     /* Please update MPEG4_ASP_START accordingly, while adding new element */
     86     {0,0,0,0,0,0},
     87 
     88     {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     89     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     90     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     91     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     92     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     93     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     94     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     95     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
     96     {0,0,0,0,0,0},
     97 };
     98 
     99 /* H264 profile and level table*/
    100 static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
    101     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
    102     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
    103     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
    104     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
    105     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
    106     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
    107     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
    108     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
    109     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
    110     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
    111     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
    112     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
    113     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
    114     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
    115     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
    116     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
    117     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
    118     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320},
    119     /* Please update H264_HP_START accordingly, while adding new element */
    120     {0,0,0,0,0,0},
    121 
    122     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
    123     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
    124     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
    125     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
    126     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
    127     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
    128     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
    129     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
    130     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
    131     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
    132     {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
    133     {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
    134     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
    135     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
    136     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
    137     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
    138     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320},
    139     /* Please update H264_MP_START accordingly, while adding new element */
    140     {0,0,0,0,0,0},
    141 
    142     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
    143     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
    144     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
    145     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
    146     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
    147     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
    148     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
    149     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
    150     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
    151     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
    152     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
    153     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
    154     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
    155     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
    156     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
    157     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
    158     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320},
    159     {0,0,0,0,0,0}
    160 
    161 };
    162 
    163 /* H263 profile and level table*/
    164 static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
    165     /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
    166     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
    167     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
    168     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
    169     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
    170     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
    171     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
    172     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
    173     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
    174     {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
    175     {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
    176     {0,0,0,0,0,0}
    177 };
    178 
    179 /* HEVC profile and level table*/
    180 static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
    181     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    182     {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
    183     {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
    184     {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
    185     {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
    186     {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
    187     {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
    188     {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
    189     {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
    190     {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
    191     {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
    192     {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
    193     {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
    194     {138240,4147200,240000000,OMX_VIDEO_HEVCHighTierLevel52,OMX_VIDEO_HEVCProfileMain,0},
    195     /* Please update HEVC_MAIN_START accordingly, while adding new element */
    196     {0,0,0,0,0},
    197 
    198     {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
    199     {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
    200     {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
    201     {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
    202     {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
    203     {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
    204     {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
    205     {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
    206     {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
    207     {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
    208     {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
    209     {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
    210     {0,0,0,0,0},
    211 };
    212 
    213 
    214 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    215 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    216 
    217 #define BUFFER_LOG_LOC "/data/misc/media"
    218 
    219 //constructor
    220 venc_dev::venc_dev(class omx_venc *venc_class):mInputExtradata(venc_class), mOutputExtradata(venc_class)
    221 {
    222     //nothing to do
    223     int i = 0;
    224     venc_handle = venc_class;
    225     etb = ebd = ftb = fbd = 0;
    226     m_poll_efd = -1;
    227 
    228     struct v4l2_control control;
    229     for (i = 0; i < MAX_PORT; i++)
    230         streaming[i] = false;
    231 
    232     stopped = 1;
    233     paused = false;
    234     async_thread_created = false;
    235     async_thread_force_stop = false;
    236     color_format = 0;
    237     hw_overload = false;
    238     mBatchSize = 0;
    239     m_profile_set = false;
    240     m_level_set = false;
    241     rc_off_level = 0;
    242     pthread_mutex_init(&pause_resume_mlock, NULL);
    243     pthread_cond_init(&pause_resume_cond, NULL);
    244     memset(&idrperiod, 0, sizeof(idrperiod));
    245     memset(&multislice, 0, sizeof(multislice));
    246     memset (&slice_mode, 0 , sizeof(slice_mode));
    247     memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
    248     memset(&rate_ctrl, 0, sizeof(rate_ctrl));
    249     memset(&bitrate, 0, sizeof(bitrate));
    250     memset(&intra_period, 0, sizeof(intra_period));
    251     memset(&codec_profile, 0, sizeof(codec_profile));
    252     memset(&set_param, 0, sizeof(set_param));
    253     memset(&time_inc, 0, sizeof(time_inc));
    254     memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
    255     memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
    256     memset(&session_qp, 0, sizeof(session_qp));
    257     memset(&entropy, 0, sizeof(entropy));
    258     memset(&dbkfilter, 0, sizeof(dbkfilter));
    259     memset(&intra_refresh, 0, sizeof(intra_refresh));
    260     memset(&hec, 0, sizeof(hec));
    261     memset(&voptimecfg, 0, sizeof(voptimecfg));
    262     memset(&capability, 0, sizeof(capability));
    263     memset(&m_debug,0,sizeof(m_debug));
    264     memset(&hier_layers,0,sizeof(hier_layers));
    265     is_searchrange_set = false;
    266     enable_mv_narrow_searchrange = false;
    267     supported_rc_modes = RC_ALL;
    268     memset(&vqzip_sei_info, 0, sizeof(vqzip_sei_info));
    269     memset(&ltrinfo, 0, sizeof(ltrinfo));
    270     memset(&fd_list, 0, sizeof(fd_list));
    271     memset(&hybrid_hp, 0, sizeof(hybrid_hp));
    272     sess_priority.priority = 1; //default to non-realtime
    273     operating_rate = 0;
    274     memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
    275     memset(&color_space, 0x0, sizeof(color_space));
    276 
    277     char property_value[PROPERTY_VALUE_MAX] = {0};
    278     property_get("vidc.enc.log.in", property_value, "0");
    279     m_debug.in_buffer_log = atoi(property_value);
    280 
    281     property_get("vidc.enc.log.out", property_value, "0");
    282     m_debug.out_buffer_log = atoi(property_value);
    283 
    284     property_get("vidc.enc.log.extradata", property_value, "0");
    285     m_debug.extradata_log = atoi(property_value);
    286 
    287     property_get("vidc.enc.log.roiqp", property_value, "0");
    288     m_debug.roiqp_log = atoi(property_value);
    289 #ifdef _UBWC_
    290     property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
    291     if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
    292         !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
    293         is_gralloc_source_ubwc = 0;
    294     } else {
    295         is_gralloc_source_ubwc = 1;
    296     }
    297 #else
    298     is_gralloc_source_ubwc = 0;
    299 #endif
    300 
    301     property_get("persist.vidc.enc.csc.enable", property_value, "0");
    302     if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
    303             !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
    304         is_csc_enabled = 1;
    305     } else {
    306         is_csc_enabled = 0;
    307     }
    308     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
    309              "%s", BUFFER_LOG_LOC);
    310 
    311     mUseAVTimerTimestamps = false;
    312 }
    313 
    314 venc_dev::~venc_dev()
    315 {
    316 }
    317 
    318 void* venc_dev::async_venc_message_thread (void *input)
    319 {
    320     struct venc_msg venc_msg;
    321     omx_video* omx_venc_base = NULL;
    322     omx_venc *omx = reinterpret_cast<omx_venc*>(input);
    323     omx_venc_base = reinterpret_cast<omx_video*>(input);
    324     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
    325 
    326     prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
    327     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    328     struct pollfd pfds[2];
    329     struct v4l2_buffer v4l2_buf;
    330     struct v4l2_event dqevent;
    331     struct statistics stats;
    332     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    333     pfds[1].events = POLLIN | POLLERR;
    334     pfds[0].fd = omx->handle->m_nDriver_fd;
    335     pfds[1].fd = omx->handle->m_poll_efd;
    336     int error_code = 0,rc=0;
    337 
    338     memset(&stats, 0, sizeof(statistics));
    339     memset(&v4l2_buf, 0, sizeof(v4l2_buf));
    340 
    341     while (!omx->handle->async_thread_force_stop) {
    342         pthread_mutex_lock(&omx->handle->pause_resume_mlock);
    343 
    344         if (omx->handle->paused) {
    345             venc_msg.msgcode = VEN_MSG_PAUSE;
    346             venc_msg.statuscode = VEN_S_SUCCESS;
    347 
    348             if (omx->async_message_process(input, &venc_msg) < 0) {
    349                 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
    350                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
    351                 break;
    352             }
    353 
    354             /* Block here until the IL client resumes us again */
    355             pthread_cond_wait(&omx->handle->pause_resume_cond,
    356                     &omx->handle->pause_resume_mlock);
    357 
    358             venc_msg.msgcode = VEN_MSG_RESUME;
    359             venc_msg.statuscode = VEN_S_SUCCESS;
    360 
    361             if (omx->async_message_process(input, &venc_msg) < 0) {
    362                 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
    363                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
    364                 break;
    365             }
    366             memset(&stats, 0, sizeof(statistics));
    367         }
    368 
    369         pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
    370 
    371         rc = poll(pfds, 2, POLL_TIMEOUT);
    372 
    373         if (!rc) {
    374             DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
    375                     omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
    376             continue;
    377         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
    378             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
    379             break;
    380         }
    381 
    382         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
    383             DEBUG_PRINT_ERROR("async_venc_message_thread interrupted to be exited");
    384             break;
    385         }
    386 
    387         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
    388             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    389             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    390             v4l2_buf.length = omx->handle->num_output_planes;
    391             v4l2_buf.m.planes = plane;
    392 
    393             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    394                 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
    395                 venc_msg.statuscode=VEN_S_SUCCESS;
    396                 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
    397                 int extra_idx = EXTRADATA_IDX(v4l2_buf.length);
    398                 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
    399                     omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr;
    400                 } else {
    401                     omxhdr->pPlatformPrivate = 0;
    402                 }
    403                 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
    404                 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
    405                 venc_msg.buf.flags = 0;
    406                 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
    407                 venc_msg.buf.clientdata=(void*)omxhdr;
    408                 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
    409 
    410                 /* TODO: ideally report other types of frames as well
    411                  * for now it doesn't look like IL client cares about
    412                  * other types
    413                  */
    414                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
    415                     venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
    416 
    417                 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
    418                     venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
    419 
    420                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
    421                     venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
    422 
    423                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
    424                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
    425 
    426                 if (omx->handle->num_output_planes > 1 && v4l2_buf.m.planes->bytesused)
    427                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
    428 
    429                 if (omxhdr->nFilledLen)
    430                     venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
    431 
    432                 omx->handle->fbd++;
    433                 stats.bytes_generated += venc_msg.buf.len;
    434 
    435                 if (omx->async_message_process(input,&venc_msg) < 0) {
    436                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    437                     break;
    438                 }
    439             }
    440         }
    441 
    442         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
    443             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    444             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    445             v4l2_buf.m.planes = plane;
    446             v4l2_buf.length = omx->handle->num_input_planes;
    447 
    448             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    449                 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
    450                 venc_msg.statuscode=VEN_S_SUCCESS;
    451                 omx->handle->ebd++;
    452 
    453                 if (omx->handle->mBatchSize) {
    454                     int bufIndex = omx->handle->mBatchInfo.retrieveBufferAt(v4l2_buf.index);
    455                     if (bufIndex < 0) {
    456                         DEBUG_PRINT_ERROR("Retrieved invalid buffer %d", v4l2_buf.index);
    457                         break;
    458                     }
    459                     if (omx->handle->mBatchInfo.isPending(bufIndex)) {
    460                         DEBUG_PRINT_LOW(" EBD for %d [v4l2-id=%d].. batch still pending",
    461                                 bufIndex, v4l2_buf.index);
    462                         //do not return to client yet
    463                         continue;
    464                     }
    465                     v4l2_buf.index = bufIndex;
    466                 }
    467                 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
    468                     omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
    469                 else
    470                     omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
    471 
    472                 int extra_idx = EXTRADATA_IDX(v4l2_buf.length);
    473                 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
    474                     omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr;
    475                     omx->handle->mInputExtradata.put((char *)omxhdr->pPlatformPrivate);
    476                 } else {
    477                     omxhdr->pPlatformPrivate = 0;
    478                 }
    479 
    480                 venc_msg.buf.clientdata=(void*)omxhdr;
    481 
    482                 DEBUG_PRINT_LOW("sending EBD %p [id=%d]", omxhdr, v4l2_buf.index);
    483                 if (omx->async_message_process(input,&venc_msg) < 0) {
    484                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    485                     break;
    486                 }
    487             }
    488         }
    489 
    490         if (pfds[0].revents & POLLPRI) {
    491             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
    492 
    493             if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    494                 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
    495                 venc_msg.statuscode = VEN_S_SUCCESS;
    496 
    497                 if (omx->async_message_process(input,&venc_msg) < 0) {
    498                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    499                     break;
    500                 }
    501 
    502                 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
    503                 venc_msg.statuscode = VEN_S_SUCCESS;
    504 
    505                 if (omx->async_message_process(input,&venc_msg) < 0) {
    506                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    507                     break;
    508                 }
    509             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
    510                 DEBUG_PRINT_ERROR("HW Overload received");
    511                 venc_msg.statuscode = VEN_S_EFAIL;
    512                 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
    513 
    514                 if (omx->async_message_process(input,&venc_msg) < 0) {
    515                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    516                     break;
    517                 }
    518             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){
    519                 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
    520                 venc_msg.msgcode = VEN_MSG_INDICATION;
    521                 venc_msg.statuscode=VEN_S_EFAIL;
    522 
    523                 if (omx->async_message_process(input,&venc_msg) < 0) {
    524                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    525                     break;
    526                 }
    527             }
    528         }
    529 
    530         /* calc avg. fps, bitrate */
    531         struct timeval tv;
    532         gettimeofday(&tv,NULL);
    533         OMX_U64 time_diff = (OMX_U32)((tv.tv_sec * 1000000 + tv.tv_usec) -
    534                 (stats.prev_tv.tv_sec * 1000000 + stats.prev_tv.tv_usec));
    535         if (time_diff >= 5000000) {
    536             if (stats.prev_tv.tv_sec) {
    537                 OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd;
    538                 float framerate = num_fbd * 1000000/(float)time_diff;
    539                 OMX_U32 bitrate = (stats.bytes_generated * 8/num_fbd) * framerate;
    540                 DEBUG_PRINT_HIGH("stats: avg. fps %0.2f, bitrate %d",
    541                     framerate, bitrate);
    542             }
    543             stats.prev_tv = tv;
    544             stats.bytes_generated = 0;
    545             stats.prev_fbd = omx->handle->fbd;
    546         }
    547 
    548     }
    549 
    550     DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
    551     return NULL;
    552 }
    553 
    554 static const int event_type[] = {
    555     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    556     V4L2_EVENT_MSM_VIDC_SYS_ERROR
    557 };
    558 
    559 static OMX_ERRORTYPE subscribe_to_events(int fd)
    560 {
    561     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    562     struct v4l2_event_subscription sub;
    563     int array_sz = sizeof(event_type)/sizeof(int);
    564     int i,rc;
    565     memset(&sub, 0, sizeof(sub));
    566 
    567     if (fd < 0) {
    568        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    569         return OMX_ErrorBadParameter;
    570     }
    571 
    572     for (i = 0; i < array_sz; ++i) {
    573         memset(&sub, 0, sizeof(sub));
    574         sub.type = event_type[i];
    575         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    576 
    577         if (rc) {
    578            DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
    579             break;
    580         }
    581     }
    582 
    583     if (i < array_sz) {
    584         for (--i; i >=0 ; i--) {
    585             memset(&sub, 0, sizeof(sub));
    586             sub.type = event_type[i];
    587             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    588 
    589             if (rc)
    590                DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    591         }
    592 
    593         eRet = OMX_ErrorNotImplemented;
    594     }
    595 
    596     return eRet;
    597 }
    598 
    599 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
    600 {
    601     OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
    602 
    603     if (!dst || !src)
    604         return 0;
    605 
    606     /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
    607      * targets, since the payload format will be different */
    608     mbi->nFormat = 1;
    609     mbi->nDataSize = src->data_size;
    610     memcpy(&mbi->data, &src->data, src->data_size);
    611 
    612     return mbi->nDataSize + sizeof(*mbi);
    613 }
    614 
    615 bool venc_dev::handle_input_extradata(void *buffer, int fd)
    616 {
    617     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
    618     OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
    619     ssize_t consumed_len = 0;
    620     int enable = 0, i = 0;
    621     int height = 0, width = 0;
    622     char *userptr;
    623     int extra_fd;
    624     unsigned offset;
    625     ssize_t extra_size;
    626     struct v4l2_control control;
    627 
    628     memset(&control, 0, sizeof(control));
    629     control.id =  V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
    630     if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &control) < 0) {
    631         return false;
    632     }
    633 
    634     if (!(control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS ||
    635         control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI ||
    636         control.value == V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP ||
    637         control.value == V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP)) {
    638         DEBUG_PRINT_LOW("Input extradata not enabled");
    639         return true;
    640     }
    641 
    642     /*
    643      * At this point encoder component doesn't know where the extradata is
    644      * located in YUV buffer. For all practical usecases, decoder appends
    645      * extradata after nFilledLen which is calcualted as 32 aligned height
    646      * and width * 3 / 2. Hence start looking for extradata from this point.
    647      */
    648 
    649     height = ALIGN(m_sVenc_cfg.input_height, 32);
    650     width = ALIGN(m_sVenc_cfg.input_width, 32);
    651 
    652     int rc = mInputExtradata.get(buffer, &userptr, &extra_fd, &offset, &extra_size);
    653     if (rc != OMX_ErrorNone) {
    654         DEBUG_PRINT_ERROR("Unable to get extradata memory 4");
    655         return false;
    656     }
    657     unsigned char *pVirt;
    658     int size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
    659     pVirt= (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
    660 
    661     p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned long)(pVirt + ((width * height * 3) / 2) + 3)&(~3));
    662     char *p_extradata = userptr;
    663     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
    664     if (p_extra) {
    665         while ((consumed_len < extra_size)
    666             && (p_extra->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
    667             DEBUG_PRINT_LOW("Extradata Type = 0x%x", (OMX_QCOM_EXTRADATATYPE)p_extra->eType);
    668             switch ((OMX_QCOM_EXTRADATATYPE)p_extra->eType) {
    669             case OMX_ExtraDataFrameDimension:
    670             {
    671                 struct msm_vidc_extradata_index *payload;
    672                 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *framedimension_format;
    673                 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_extradata_index) + 3)&(~3);
    674                 data->nVersion.nVersion = OMX_SPEC_VERSION;
    675                 data->nPortIndex = 0;
    676                 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_INDEX;
    677                 data->nDataSize = sizeof(struct msm_vidc_input_crop_payload);
    678                 framedimension_format = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)p_extra->data;
    679                 payload = (struct msm_vidc_extradata_index *)(data->data);
    680                 payload->type = (msm_vidc_extradata_type)MSM_VIDC_EXTRADATA_INPUT_CROP;
    681                 payload->input_crop.left = framedimension_format->nDecWidth;
    682                 payload->input_crop.top = framedimension_format->nDecHeight;
    683                 payload->input_crop.width = framedimension_format->nActualWidth;
    684                 payload->input_crop.height = framedimension_format->nActualHeight;
    685                 DEBUG_PRINT_LOW("Height = %d Width = %d Actual Height = %d Actual Width = %d",
    686                     framedimension_format->nDecWidth, framedimension_format->nDecHeight,
    687                     framedimension_format->nActualWidth, framedimension_format->nActualHeight);
    688                 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
    689                 break;
    690             }
    691             case OMX_ExtraDataQP:
    692             {
    693                 OMX_QCOM_EXTRADATA_QP * qp_payload = NULL;
    694                 struct msm_vidc_frame_qp_payload *payload;
    695                 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_frame_qp_payload) + 3)&(~3);
    696                 data->nVersion.nVersion = OMX_SPEC_VERSION;
    697                 data->nPortIndex = 0;
    698                 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_FRAME_QP;
    699                 data->nDataSize = sizeof(struct  msm_vidc_frame_qp_payload);
    700                 qp_payload = (OMX_QCOM_EXTRADATA_QP *)p_extra->data;
    701                 payload = (struct  msm_vidc_frame_qp_payload *)(data->data);
    702                 payload->frame_qp = qp_payload->nQP;
    703                 DEBUG_PRINT_LOW("Frame QP = %d", payload->frame_qp);
    704                 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
    705                 break;
    706             }
    707             case OMX_ExtraDataVQZipSEI:
    708                 DEBUG_PRINT_LOW("VQZIP SEI Found ");
    709                 mInputExtradata.vqzip_sei_found = true;
    710                 break;
    711             default:
    712                 break;
    713             }
    714             consumed_len += p_extra->nSize;
    715             p_extra = (OMX_OTHER_EXTRADATATYPE *)((char *)p_extra + p_extra->nSize);
    716         }
    717 
    718         if (control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS ||
    719             control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI) {
    720             if (!mInputExtradata.vqzip_sei_found) {
    721                 DEBUG_PRINT_ERROR("VQZIP is enabled, But no VQZIP SEI found. Rejecting the session");
    722                 munmap(pVirt, size);
    723                 mInputExtradata.put(userptr);
    724                 return false;
    725             }
    726 #ifdef _VQZIP_
    727             data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) +  sizeof(struct VQZipStats) + 3)&(~3);
    728             data->nVersion.nVersion = OMX_SPEC_VERSION;
    729             data->nPortIndex = 0;
    730             data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_YUVSTATS_INFO;
    731             data->nDataSize = sizeof(struct VQZipStats);
    732             vqzip.fill_stats_data((void*)pVirt, (void*) data->data);
    733             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
    734 #endif
    735         }
    736 
    737         data->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
    738         data->nVersion.nVersion = OMX_SPEC_VERSION;
    739         data->eType = OMX_ExtraDataNone;
    740         data->nDataSize = 0;
    741         data->data[0] = 0;
    742 
    743     }
    744     munmap(pVirt, size);
    745     mInputExtradata.put(userptr);
    746     return true;
    747 }
    748 
    749 bool venc_dev::handle_output_extradata(void *buffer)
    750 {
    751     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
    752     OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
    753     char *extradata_uaddr = (char *)p_bufhdr->pPlatformPrivate;
    754 
    755     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
    756                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
    757 
    758     if (mOutputExtradata.getBufferSize() >
    759             (ssize_t)(p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4))) {
    760         DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
    761         p_extra = NULL;
    762         return false;
    763     } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
    764         /* A lot of the code below assumes this condition, so error out if it's not met */
    765         DEBUG_PRINT_ERROR("Extradata ABI mismatch");
    766         return false;
    767     }
    768 
    769     struct msm_vidc_extradata_header *p_extradata = NULL;
    770     do {
    771         p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
    772             ((char *)p_extradata) + p_extradata->size : extradata_uaddr);
    773 
    774         switch (p_extradata->type) {
    775             case MSM_VIDC_EXTRADATA_METADATA_MBI:
    776             {
    777                 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
    778                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
    779                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
    780                 p_extra->nPortIndex = OMX_DirOutput;
    781                 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
    782                 p_extra->nDataSize = payloadSize;
    783                 break;
    784             }
    785             case MSM_VIDC_EXTRADATA_METADATA_LTR:
    786             {
    787                 *p_extra->data = *p_extradata->data;
    788                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
    789                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
    790                 p_extra->nPortIndex = OMX_DirOutput;
    791                 p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
    792                 p_extra->nDataSize = p_extradata->data_size;
    793                 break;
    794             }
    795             case MSM_VIDC_EXTRADATA_NONE:
    796                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
    797                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
    798                 p_extra->nPortIndex = OMX_DirOutput;
    799                 p_extra->eType = OMX_ExtraDataNone;
    800                 p_extra->nDataSize = 0;
    801                 break;
    802             default:
    803                 /* No idea what this stuff is, just skip over it */
    804                 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
    805                         p_extradata->type);
    806                 continue;
    807         }
    808 
    809         p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
    810     } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
    811 
    812     /* Just for debugging: Traverse the list of extra datas  and spit it out onto log */
    813     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
    814                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
    815     while(p_extra->eType != OMX_ExtraDataNone)
    816     {
    817         DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
    818                 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
    819                 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
    820 
    821         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
    822                 p_extra->nSize);
    823     }
    824     mOutputExtradata.put(extradata_uaddr);
    825     return true;
    826 }
    827 
    828 int venc_dev::venc_set_format(int format)
    829 {
    830     int rc = true;
    831 
    832     if (format) {
    833         color_format = format;
    834 
    835         switch (color_format) {
    836         case NV12_128m:
    837             return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m);
    838         default:
    839             return false;
    840         }
    841 
    842     } else {
    843         color_format = 0;
    844         rc = false;
    845     }
    846 
    847     return rc;
    848 }
    849 
    850 bool venc_dev::venc_get_output_log_flag()
    851 {
    852     return (m_debug.out_buffer_log == 1);
    853 }
    854 
    855 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
    856 {
    857     if (venc_handle->is_secure_session()) {
    858         DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
    859         return -1;
    860     }
    861 
    862     if (!m_debug.outfile) {
    863         int size = 0;
    864         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
    865            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
    866                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    867         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
    868            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
    869                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    870         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
    871            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
    872                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    873         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
    874            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
    875                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    876         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
    877            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
    878                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    879         }
    880         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    881              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
    882                                 m_debug.outfile_name, size);
    883         }
    884         m_debug.outfile = fopen(m_debug.outfile_name, "ab");
    885         if (!m_debug.outfile) {
    886             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
    887                                m_debug.outfile_name, errno);
    888             m_debug.outfile_name[0] = '\0';
    889             return -1;
    890         }
    891     }
    892     if (m_debug.outfile && buffer_len) {
    893         DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
    894         fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
    895     }
    896     return 0;
    897 }
    898 
    899 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
    900 {
    901     if (!m_debug.extradatafile && m_debug.extradata_log) {
    902         int size = 0;
    903         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
    904            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
    905                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    906         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
    907            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
    908                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    909         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
    910            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265",
    911                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    912         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
    913            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
    914                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    915         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
    916            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
    917                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    918         }
    919         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    920              DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
    921                                 m_debug.extradatafile_name, size);
    922         }
    923 
    924         m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
    925         if (!m_debug.extradatafile) {
    926             DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
    927                                m_debug.extradatafile_name, errno);
    928             m_debug.extradatafile_name[0] = '\0';
    929             return -1;
    930         }
    931     }
    932 
    933     if (m_debug.extradatafile) {
    934         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
    935         do {
    936             p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
    937                     ((char *)p_extra) + p_extra->nSize);
    938             fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
    939         } while (p_extra->eType != OMX_ExtraDataNone);
    940     }
    941     return 0;
    942 }
    943 
    944 int venc_dev::venc_roiqp_log_buffers(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
    945     int size = 0;
    946     if (!roiInfo || !m_debug.roiqp_log) {
    947         DEBUG_PRINT_LOW("Nothing to log");
    948         return 0;
    949     }
    950     if (!m_debug.roiqpfile) {
    951         size = snprintf(m_debug.roiqpfile_name, PROPERTY_VALUE_MAX, "%s/enc_%lu_%lu_%p.roiqp",
    952                 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    953         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    954             DEBUG_PRINT_ERROR("Failed to open ROIQP file: %s for logging size:%d",
    955                     m_debug.roiqpfile_name, size);
    956             m_debug.roiqpfile_name[0] = '\0';
    957             return -1;
    958         }
    959         m_debug.roiqpfile = fopen(m_debug.roiqpfile_name, "ab");
    960         if (!m_debug.roiqpfile) {
    961             DEBUG_PRINT_ERROR("Failed to open ROI QP file: %s for logging errno:%d",
    962                     m_debug.roiqpfile_name, errno);
    963             m_debug.roiqpfile_name[0] = '\0';
    964             return -1;
    965         }
    966     }
    967     if (m_debug.roiqpfile) {
    968         if (fwrite(&mInputExtradata.mDbgEtbCount, sizeof(mInputExtradata.mDbgEtbCount), 1, m_debug.roiqpfile) != 1) {
    969             DEBUG_PRINT_ERROR("Unable to write to QP file");
    970             return -1;
    971         }
    972         if (fwrite(&roiInfo->nLowerQpOffset, sizeof(roiInfo->nLowerQpOffset), 1, m_debug.roiqpfile) != 1) {
    973             DEBUG_PRINT_ERROR("Unable to write to QP file");
    974             return -1;
    975         }
    976         if (fwrite(&roiInfo->nUpperQpOffset, sizeof(roiInfo->nUpperQpOffset), 1, m_debug.roiqpfile) != 1) {
    977             DEBUG_PRINT_ERROR("Unable to write to QP file");
    978             return -1;
    979         }
    980         if (fwrite((char *)roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize, 1, m_debug.roiqpfile) != 1) {
    981             DEBUG_PRINT_ERROR("Unable to write to QP file");
    982             return -1;
    983         }
    984     }
    985     return 0;
    986 }
    987 
    988 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset,
    989         unsigned long inputformat) {
    990     if (venc_handle->is_secure_session()) {
    991         DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
    992         return -1;
    993     }
    994 
    995     if (!m_debug.infile) {
    996         int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
    997                             m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    998         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    999              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
   1000                                 m_debug.infile_name, size);
   1001         }
   1002         m_debug.infile = fopen (m_debug.infile_name, "ab");
   1003         if (!m_debug.infile) {
   1004             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
   1005             m_debug.infile_name[0] = '\0';
   1006             return -1;
   1007         }
   1008     }
   1009 
   1010     if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
   1011         int stride, scanlines;
   1012         int color_format;
   1013         unsigned long i, msize;
   1014         unsigned char *pvirt = NULL, *ptemp = NULL;
   1015         unsigned char *temp = (unsigned char *)pbuffer->pBuffer;
   1016 
   1017         switch (inputformat) {
   1018             case V4L2_PIX_FMT_NV12:
   1019                 color_format = COLOR_FMT_NV12;
   1020                 break;
   1021             case V4L2_PIX_FMT_NV12_UBWC:
   1022                 color_format = COLOR_FMT_NV12_UBWC;
   1023                 break;
   1024             case V4L2_PIX_FMT_RGB32:
   1025                 color_format = COLOR_FMT_RGBA8888;
   1026                 break;
   1027             case V4L2_PIX_FMT_RGBA8888_UBWC:
   1028                 color_format = COLOR_FMT_RGBA8888_UBWC;
   1029                 break;
   1030             default:
   1031                 color_format = COLOR_FMT_NV12;
   1032                 DEBUG_PRINT_LOW("Default format NV12 is set for logging [%lu]", inputformat);
   1033                 break;
   1034         }
   1035 
   1036         msize = VENUS_BUFFER_SIZE(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
   1037         const unsigned int extra_size = VENUS_EXTRADATA_SIZE(m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
   1038 
   1039         if (metadatamode == 1) {
   1040             pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
   1041             if (pvirt == MAP_FAILED) {
   1042                 DEBUG_PRINT_ERROR("%s mmap failed", __func__);
   1043                 return -1;
   1044             }
   1045             ptemp = pvirt;
   1046         } else {
   1047             ptemp = temp;
   1048         }
   1049 
   1050         if (color_format == COLOR_FMT_NV12) {
   1051             stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
   1052             scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
   1053 
   1054             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
   1055                 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
   1056                 ptemp += stride;
   1057             }
   1058             if (metadatamode == 1) {
   1059                 ptemp = pvirt + (stride * scanlines);
   1060             } else {
   1061                 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
   1062             }
   1063             for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
   1064                 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
   1065                 ptemp += stride;
   1066             }
   1067         } else if (color_format == COLOR_FMT_RGBA8888) {
   1068             stride = VENUS_RGB_STRIDE(color_format, m_sVenc_cfg.input_width);
   1069             scanlines = VENUS_RGB_SCANLINES(color_format, m_sVenc_cfg.input_height);
   1070 
   1071             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
   1072                 fwrite(ptemp, m_sVenc_cfg.input_width * 4, 1, m_debug.infile);
   1073                 ptemp += stride;
   1074             }
   1075         } else if (color_format == COLOR_FMT_NV12_UBWC || color_format == COLOR_FMT_RGBA8888_UBWC) {
   1076             if (color_format == COLOR_FMT_NV12_UBWC) {
   1077                 msize -= 2 * extra_size;
   1078             }
   1079             fwrite(ptemp, msize, 1, m_debug.infile);
   1080         }
   1081 
   1082         if (metadatamode == 1 && pvirt) {
   1083             munmap(pvirt, msize);
   1084         }
   1085     }
   1086 
   1087     return 0;
   1088 }
   1089 
   1090 bool venc_dev::venc_open(OMX_U32 codec)
   1091 {
   1092     int r;
   1093     unsigned int alignment = 0,buffer_size = 0, temp =0;
   1094     struct v4l2_control control;
   1095     OMX_STRING device_name = (OMX_STRING)"/dev/video33";
   1096     char property_value[PROPERTY_VALUE_MAX] = {0};
   1097     char platform_name[PROPERTY_VALUE_MAX] = {0};
   1098     FILE *soc_file = NULL;
   1099     char buffer[10];
   1100 
   1101     property_get("ro.board.platform", platform_name, "0");
   1102     property_get("vidc.enc.narrow.searchrange", property_value, "0");
   1103     enable_mv_narrow_searchrange = atoi(property_value);
   1104 
   1105     if (!strncmp(platform_name, "msm8610", 7)) {
   1106         device_name = (OMX_STRING)"/dev/video/q6_enc";
   1107         supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
   1108     }
   1109     m_nDriver_fd = open (device_name, O_RDWR);
   1110     if ((int)m_nDriver_fd < 0) {
   1111         DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
   1112         return false;
   1113     }
   1114     m_poll_efd = eventfd(0, 0);
   1115     if (m_poll_efd < 0) {
   1116         DEBUG_PRINT_ERROR("Failed to open event fd(%s)", strerror(errno));
   1117         return false;
   1118     }
   1119     DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
   1120 
   1121     // set the basic configuration of the video encoder driver
   1122     m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
   1123     m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
   1124     m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
   1125     m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
   1126     m_sVenc_cfg.fps_num = 30;
   1127     m_sVenc_cfg.fps_den = 1;
   1128     m_sVenc_cfg.targetbitrate = 64000;
   1129     m_sVenc_cfg.inputformat= V4L2_DEFAULT_OUTPUT_COLOR_FMT;
   1130 
   1131     m_codec = codec;
   1132 
   1133     if (codec == OMX_VIDEO_CodingMPEG4) {
   1134         m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
   1135         codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
   1136         profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
   1137         session_qp_range.minqp = 1;
   1138         session_qp_range.maxqp = 31;
   1139     } else if (codec == OMX_VIDEO_CodingH263) {
   1140         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
   1141         codec_profile.profile = VEN_PROFILE_H263_BASELINE;
   1142         profile_level.level = VEN_LEVEL_H263_20;
   1143         session_qp_range.minqp = 1;
   1144         session_qp_range.maxqp = 31;
   1145     } else if (codec == OMX_VIDEO_CodingAVC) {
   1146         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
   1147         codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
   1148         profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
   1149         session_qp_range.minqp = 1;
   1150         session_qp_range.maxqp = 51;
   1151     } else if (codec == OMX_VIDEO_CodingVP8) {
   1152         m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
   1153         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
   1154         profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
   1155         session_qp_range.minqp = 1;
   1156         session_qp_range.maxqp = 128;
   1157     } else if (codec == OMX_VIDEO_CodingHEVC) {
   1158         m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
   1159         session_qp_range.minqp = 1;
   1160         session_qp_range.maxqp = 51;
   1161         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
   1162         profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
   1163     }
   1164     session_qp_values.minqp = session_qp_range.minqp;
   1165     session_qp_values.maxqp = session_qp_range.maxqp;
   1166 
   1167     int ret;
   1168     ret = subscribe_to_events(m_nDriver_fd);
   1169 
   1170     if (ret) {
   1171         DEBUG_PRINT_ERROR("Subscribe Event Failed");
   1172         return false;
   1173     }
   1174 
   1175     struct v4l2_fmtdesc fdesc;
   1176     struct v4l2_format fmt;
   1177     struct v4l2_requestbuffers bufreq;
   1178     struct v4l2_capability cap;
   1179 
   1180     ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
   1181 
   1182     if (ret) {
   1183         DEBUG_PRINT_ERROR("Failed to query capabilities");
   1184     } else {
   1185         DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   1186                 " version = %d, capabilities = %x", cap.driver, cap.card,
   1187                 cap.bus_info, cap.version, cap.capabilities);
   1188     }
   1189 
   1190     ret=0;
   1191     fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1192     fdesc.index=0;
   1193 
   1194     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   1195         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   1196                 fdesc.pixelformat, fdesc.flags);
   1197         fdesc.index++;
   1198     }
   1199 
   1200     fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1201     fdesc.index=0;
   1202 
   1203     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   1204         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   1205                 fdesc.pixelformat, fdesc.flags);
   1206         fdesc.index++;
   1207     }
   1208 
   1209     is_thulium_v1 = false;
   1210     soc_file= fopen("/sys/devices/soc0/soc_id", "r");
   1211     if (soc_file) {
   1212         fread(buffer, 1, 4, soc_file);
   1213         fclose(soc_file);
   1214         if (atoi(buffer) == 246) {
   1215             soc_file = fopen("/sys/devices/soc0/revision", "r");
   1216             if (soc_file) {
   1217                 fread(buffer, 1, 4, soc_file);
   1218                 fclose(soc_file);
   1219                 if (atoi(buffer) == 1) {
   1220                     is_thulium_v1 = true;
   1221                     DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
   1222                 }
   1223             }
   1224         }
   1225     }
   1226 
   1227     if (venc_handle->is_secure_session()) {
   1228         m_sOutput_buff_property.alignment = SZ_1M;
   1229         m_sInput_buff_property.alignment  = SZ_1M;
   1230     } else {
   1231         m_sOutput_buff_property.alignment = SZ_4K;
   1232         m_sInput_buff_property.alignment  = SZ_4K;
   1233     }
   1234 
   1235     memset(&fmt, 0, sizeof(fmt));
   1236     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1237     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1238     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1239     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1240 
   1241     /*TODO: Return values not handled properly in this function anywhere.
   1242      * Need to handle those.*/
   1243     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
   1244 
   1245     if (ret) {
   1246         DEBUG_PRINT_ERROR("Failed to set format on capture port");
   1247         return false;
   1248     }
   1249 
   1250     m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1251 
   1252     memset(&fmt, 0, sizeof(fmt));
   1253     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1254     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   1255     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   1256     fmt.fmt.pix_mp.pixelformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
   1257     fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
   1258 
   1259     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
   1260     m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1261 
   1262     bufreq.memory = V4L2_MEMORY_USERPTR;
   1263     bufreq.count = 2;
   1264 
   1265     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1266     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
   1267     m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
   1268 
   1269     bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1270     bufreq.count = 2;
   1271     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
   1272     m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
   1273 
   1274     if(venc_handle->is_secure_session()) {
   1275         control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   1276         control.value = 1;
   1277         DEBUG_PRINT_HIGH("ioctl: open secure device");
   1278         ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
   1279         if (ret) {
   1280             DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
   1281             return false;
   1282         }
   1283     }
   1284 
   1285     resume_in_stopped = 0;
   1286     metadatamode = 0;
   1287 
   1288     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
   1289     control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
   1290 
   1291     DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
   1292 
   1293     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
   1294         DEBUG_PRINT_ERROR("Failed to set control");
   1295 
   1296     struct v4l2_frmsizeenum frmsize;
   1297 
   1298     //Get the hardware capabilities
   1299     memset((void *)&frmsize,0,sizeof(frmsize));
   1300     frmsize.index = 0;
   1301     frmsize.pixel_format = m_sVenc_cfg.codectype;
   1302     ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
   1303 
   1304     if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   1305         DEBUG_PRINT_ERROR("Failed to get framesizes");
   1306         return false;
   1307     }
   1308 
   1309     if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   1310         capability.min_width = frmsize.stepwise.min_width;
   1311         capability.max_width = frmsize.stepwise.max_width;
   1312         capability.min_height = frmsize.stepwise.min_height;
   1313         capability.max_height = frmsize.stepwise.max_height;
   1314     }
   1315 
   1316     //Initialize non-default parameters
   1317     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   1318         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
   1319         control.value = 0x7fffffff;
   1320         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
   1321             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
   1322     }
   1323 
   1324     property_get("vidc.debug.turbo", property_value, "0");
   1325     if (atoi(property_value)) {
   1326         DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
   1327         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   1328         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   1329         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   1330             DEBUG_PRINT_ERROR("Failed to set turbo mode");
   1331         }
   1332     }
   1333     return true;
   1334 }
   1335 
   1336 
   1337 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
   1338 {
   1339     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1340     struct v4l2_event_subscription sub;
   1341     int array_sz = sizeof(event_type)/sizeof(int);
   1342     int i,rc;
   1343 
   1344     if (fd < 0) {
   1345        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
   1346         return OMX_ErrorBadParameter;
   1347     }
   1348 
   1349     for (i = 0; i < array_sz; ++i) {
   1350         memset(&sub, 0, sizeof(sub));
   1351         sub.type = event_type[i];
   1352         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
   1353 
   1354         if (rc) {
   1355            DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
   1356             break;
   1357         }
   1358     }
   1359 
   1360     return eRet;
   1361 }
   1362 
   1363 void venc_dev::venc_close()
   1364 {
   1365     DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
   1366 
   1367     if ((int)m_nDriver_fd >= 0) {
   1368         DEBUG_PRINT_HIGH("venc_close E");
   1369 
   1370         if(eventfd_write(m_poll_efd, 1)) {
   1371             DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
   1372             async_thread_force_stop = true;
   1373         }
   1374 
   1375         if (async_thread_created)
   1376             pthread_join(m_tid,NULL);
   1377 
   1378         DEBUG_PRINT_HIGH("venc_close X");
   1379         unsubscribe_to_events(m_nDriver_fd);
   1380         close(m_poll_efd);
   1381         close(m_nDriver_fd);
   1382         m_nDriver_fd = -1;
   1383     }
   1384 
   1385     if (m_debug.infile) {
   1386         fclose(m_debug.infile);
   1387         m_debug.infile = NULL;
   1388     }
   1389 
   1390     if (m_debug.outfile) {
   1391         fclose(m_debug.outfile);
   1392         m_debug.outfile = NULL;
   1393     }
   1394 
   1395     if (m_debug.extradatafile) {
   1396         fclose(m_debug.extradatafile);
   1397         m_debug.extradatafile = NULL;
   1398     }
   1399 
   1400     if (m_debug.roiqpfile) {
   1401         fclose(m_debug.roiqpfile);
   1402         m_debug.roiqpfile = NULL;
   1403     }
   1404 }
   1405 
   1406 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
   1407         OMX_U32 *actual_buff_count,
   1408         OMX_U32 *buff_size,
   1409         OMX_U32 port)
   1410 {
   1411     (void)min_buff_count, (void)buff_size;
   1412     unsigned long temp_count = 0;
   1413 
   1414     if (port == 0) {
   1415         if (*actual_buff_count > m_sInput_buff_property.mincount) {
   1416             temp_count = m_sInput_buff_property.actualcount;
   1417             m_sInput_buff_property.actualcount = *actual_buff_count;
   1418             DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
   1419         }
   1420     } else {
   1421         if (*actual_buff_count > m_sOutput_buff_property.mincount) {
   1422             temp_count = m_sOutput_buff_property.actualcount;
   1423             m_sOutput_buff_property.actualcount = *actual_buff_count;
   1424             DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
   1425         }
   1426     }
   1427 
   1428     return true;
   1429 
   1430 }
   1431 
   1432 bool venc_dev::venc_loaded_start()
   1433 {
   1434     return true;
   1435 }
   1436 
   1437 bool venc_dev::venc_loaded_stop()
   1438 {
   1439     return true;
   1440 }
   1441 
   1442 bool venc_dev::venc_loaded_start_done()
   1443 {
   1444     return true;
   1445 }
   1446 
   1447 bool venc_dev::venc_loaded_stop_done()
   1448 {
   1449     return true;
   1450 }
   1451 
   1452 bool venc_dev::venc_get_seq_hdr(void *buffer,
   1453         unsigned buffer_size, unsigned *header_len)
   1454 {
   1455     (void) buffer, (void) buffer_size, (void) header_len;
   1456     return true;
   1457 }
   1458 
   1459 bool venc_dev::venc_get_dimensions(OMX_U32 portIndex, OMX_U32 *w, OMX_U32 *h) {
   1460     struct v4l2_format fmt;
   1461     memset(&fmt, 0, sizeof(fmt));
   1462     fmt.type = portIndex == PORT_INDEX_OUT ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
   1463             V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1464 
   1465     if (ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt)) {
   1466         DEBUG_PRINT_ERROR("Failed to get format on %s port",
   1467                 portIndex == PORT_INDEX_OUT ? "capture" : "output");
   1468         return false;
   1469     }
   1470     *w = fmt.fmt.pix_mp.width;
   1471     *h = fmt.fmt.pix_mp.height;
   1472     return true;
   1473 }
   1474 
   1475 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
   1476         OMX_U32 *actual_buff_count,
   1477         OMX_U32 *buff_size,
   1478         OMX_U32 port)
   1479 {
   1480     struct v4l2_format fmt;
   1481     struct v4l2_requestbuffers bufreq;
   1482     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
   1483     int ret;
   1484     int extra_idx = 0;
   1485 
   1486     if (port == 0) {
   1487         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1488         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   1489         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   1490         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   1491         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
   1492         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
   1493         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1494         bufreq.memory = V4L2_MEMORY_USERPTR;
   1495 
   1496         if (*actual_buff_count)
   1497             bufreq.count = *actual_buff_count;
   1498         else
   1499             bufreq.count = 2;
   1500 
   1501         // Increase buffer-header count for metadata-mode on input port
   1502         // to improve buffering and reduce bottlenecks in clients
   1503         if (metadatamode && (bufreq.count < 9)) {
   1504             DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9",
   1505                 bufreq.count);
   1506             bufreq.count = 9;
   1507         }
   1508         if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) {
   1509             DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count);
   1510             bufreq.count = 11;
   1511         }
   1512 
   1513         int actualCount = bufreq.count;
   1514         // Request MAX_V4L2_BUFS from V4L2 in batch mode.
   1515         // Keep the original count for the client
   1516         if (metadatamode && mBatchSize) {
   1517             bufreq.count = MAX_V4L2_BUFS;
   1518         }
   1519 
   1520         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1521         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
   1522 
   1523         if (ret) {
   1524             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
   1525             return false;
   1526         }
   1527         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1528         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   1529         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   1530         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   1531         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
   1532         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1533 
   1534         m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = actualCount;
   1535         *min_buff_count = m_sInput_buff_property.mincount;
   1536         *actual_buff_count = m_sInput_buff_property.actualcount;
   1537 #ifdef USE_ION
   1538         // For ION memory allocations of the allocated buffer size
   1539         // must be 4k aligned, hence aligning the input buffer
   1540         // size to 4k.
   1541         m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
   1542 #endif
   1543         *buff_size = m_sInput_buff_property.datasize;
   1544         num_input_planes = fmt.fmt.pix_mp.num_planes;
   1545         extra_idx = EXTRADATA_IDX(num_input_planes);
   1546 
   1547         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   1548             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   1549         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   1550             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
   1551             return OMX_ErrorBadParameter;
   1552         }
   1553         mInputExtradata.update(m_sInput_buff_property.actualcount + 1, extra_data_size);
   1554     } else {
   1555         unsigned int extra_idx = 0;
   1556         memset(&fmt, 0, sizeof(fmt));
   1557         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1558         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1559         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1560         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1561 
   1562         ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
   1563         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1564         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1565         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1566         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1567         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1568 
   1569         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
   1570         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1571         bufreq.memory = V4L2_MEMORY_USERPTR;
   1572 
   1573         if (mBatchSize) {
   1574             // If we're in batch mode, we'd like to end up in a situation where
   1575             // driver is able to own mBatchSize buffers and we'd also own atleast
   1576             // mBatchSize buffers
   1577             bufreq.count = MAX(*actual_buff_count, mBatchSize) + mBatchSize;
   1578         } else if (*actual_buff_count) {
   1579             bufreq.count = *actual_buff_count;
   1580         } else {
   1581             bufreq.count = 2;
   1582         }
   1583 
   1584         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1585         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
   1586 
   1587         if (ret) {
   1588             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
   1589             return false;
   1590         }
   1591 
   1592         m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
   1593         *min_buff_count = m_sOutput_buff_property.mincount;
   1594         *actual_buff_count = m_sOutput_buff_property.actualcount;
   1595         *buff_size = m_sOutput_buff_property.datasize;
   1596         num_output_planes = fmt.fmt.pix_mp.num_planes;
   1597         extra_idx = EXTRADATA_IDX(num_output_planes);
   1598 
   1599         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   1600             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   1601         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   1602             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   1603             return OMX_ErrorBadParameter;
   1604         }
   1605         mOutputExtradata.update(m_sOutput_buff_property.actualcount, extra_data_size);
   1606     }
   1607 
   1608     return true;
   1609 }
   1610 
   1611 bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index)
   1612 {
   1613     DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
   1614     struct v4l2_format fmt;
   1615     struct v4l2_requestbuffers bufreq;
   1616     int ret;
   1617 
   1618     switch ((int)index) {
   1619         case OMX_IndexParamPortDefinition:
   1620             {
   1621                 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   1622                 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   1623                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
   1624 
   1625                 if (portDefn->nPortIndex == PORT_INDEX_IN) {
   1626                     if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
   1627                         return false;
   1628                     }
   1629 
   1630                     if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
   1631                         return false;
   1632                     }
   1633                     if (enable_mv_narrow_searchrange &&
   1634                         (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
   1635                         (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
   1636                         if (venc_set_searchrange() == false) {
   1637                             DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
   1638                         }
   1639                     }
   1640                     if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
   1641                             m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
   1642                         DEBUG_PRINT_LOW("Basic parameter has changed");
   1643                         m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
   1644                         m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
   1645 
   1646                         memset(&fmt, 0, sizeof(fmt));
   1647                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1648                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   1649                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   1650                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   1651                         fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
   1652 
   1653                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   1654                             DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
   1655                             hw_overload = errno == EBUSY;
   1656                             return false;
   1657                         }
   1658 
   1659                         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1660                         bufreq.memory = V4L2_MEMORY_USERPTR;
   1661                         bufreq.count = portDefn->nBufferCountActual;
   1662                         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1663 
   1664                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   1665                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
   1666                             return false;
   1667                         }
   1668 
   1669                         if (bufreq.count == portDefn->nBufferCountActual)
   1670                             m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
   1671 
   1672                         if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
   1673                             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
   1674                     }
   1675 
   1676                     DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
   1677                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
   1678                 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
   1679                     m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
   1680                     m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
   1681 
   1682                     memset(&fmt, 0, sizeof(fmt));
   1683                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1684                     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1685                     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1686                     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1687 
   1688                     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   1689                         DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
   1690                         hw_overload = errno == EBUSY;
   1691                         return false;
   1692                     }
   1693 
   1694                     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1695 
   1696                     if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
   1697                         return false;
   1698                     }
   1699 
   1700                         m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
   1701                         bufreq.memory = V4L2_MEMORY_USERPTR;
   1702                         bufreq.count = portDefn->nBufferCountActual;
   1703                         bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1704 
   1705                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   1706                             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
   1707                                     (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
   1708                             return false;
   1709                         }
   1710 
   1711                         if (bufreq.count == portDefn->nBufferCountActual)
   1712                             m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
   1713 
   1714                         if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
   1715                             m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
   1716 
   1717                     DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
   1718                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
   1719                 } else {
   1720                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
   1721                 }
   1722 
   1723                 break;
   1724             }
   1725         case OMX_IndexParamVideoPortFormat:
   1726             {
   1727                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
   1728                 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   1729                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
   1730 
   1731                 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
   1732                     if (!venc_set_color_format(portFmt->eColorFormat)) {
   1733                         return false;
   1734                     }
   1735                 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1736                     if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
   1737                         return false;
   1738                     }
   1739                 } else {
   1740                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
   1741                 }
   1742 
   1743                 break;
   1744             }
   1745         case OMX_IndexParamVideoBitrate:
   1746             {
   1747                 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
   1748                 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
   1749                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
   1750 
   1751                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1752                     if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
   1753                         DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
   1754                         return false;
   1755                     }
   1756 
   1757                     if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
   1758                         DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
   1759                         return false;
   1760                     }
   1761                 } else {
   1762                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
   1763                 }
   1764 
   1765                 break;
   1766             }
   1767         case OMX_IndexParamVideoMpeg4:
   1768             {
   1769                 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
   1770                 OMX_U32 bFrames = 0;
   1771 
   1772                 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
   1773                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
   1774 
   1775                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1776                     if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
   1777                         DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
   1778                         return false;
   1779                     }
   1780 
   1781                     m_profile_set = false;
   1782                     m_level_set = false;
   1783                     rc_off_level = (int)pParam->eLevel;
   1784                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1785                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
   1786                         return false;
   1787                     } else {
   1788                         if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
   1789                             if (pParam->nBFrames) {
   1790                                 bFrames = pParam->nBFrames;
   1791                             }
   1792                         } else {
   1793                             if (pParam->nBFrames) {
   1794                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
   1795                                 bFrames = 0;
   1796                             }
   1797                         }
   1798                     }
   1799 
   1800                     if (!venc_set_intra_period_config (pParam->nPFrames,bFrames)) {
   1801                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1802                         return false;
   1803                     }
   1804 
   1805                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
   1806                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
   1807                         return false;
   1808                     }
   1809                 } else {
   1810                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
   1811                 }
   1812 
   1813                 break;
   1814             }
   1815         case OMX_IndexParamVideoH263:
   1816             {
   1817                 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
   1818                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
   1819                 OMX_U32 bFrames = 0;
   1820 
   1821                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1822                     m_profile_set = false;
   1823                     m_level_set = false;
   1824                     rc_off_level = (int)pParam->eLevel;
   1825                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1826                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
   1827                         return false;
   1828                     }
   1829 
   1830                     if (pParam->nBFrames)
   1831                         DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
   1832 
   1833                     if (venc_set_intra_period_config (pParam->nPFrames, bFrames) == false) {
   1834                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1835                         return false;
   1836                     }
   1837                 } else {
   1838                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
   1839                 }
   1840 
   1841                 break;
   1842             }
   1843         case OMX_IndexParamVideoAvc:
   1844             {
   1845                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
   1846                 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
   1847                 OMX_U32 bFrames = 0;
   1848 
   1849                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1850                     DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
   1851                             pParam->eProfile,pParam->eLevel);
   1852 
   1853                     m_profile_set = false;
   1854                     m_level_set = false;
   1855                     rc_off_level = (int)pParam->eLevel;
   1856                     if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
   1857                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
   1858                                 pParam->eProfile, pParam->eLevel);
   1859                         return false;
   1860                     } else {
   1861                         if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
   1862                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) OMX_VIDEO_AVCProfileConstrainedBaseline) &&
   1863                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
   1864                             if (pParam->nBFrames) {
   1865                                 bFrames = pParam->nBFrames;
   1866                             }
   1867                         } else {
   1868                             if (pParam->nBFrames) {
   1869                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
   1870                                 bFrames = 0;
   1871                             }
   1872                         }
   1873                     }
   1874 
   1875                     if (!venc_set_intra_period_config (pParam->nPFrames, bFrames)) {
   1876                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1877                         return false;
   1878                     }
   1879 
   1880                     if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
   1881                         DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
   1882                         return false;
   1883                     }
   1884 
   1885                     if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
   1886                         DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
   1887                         return false;
   1888                     }
   1889 
   1890                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
   1891                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
   1892                         return false;
   1893                     }
   1894                 } else {
   1895                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
   1896                 }
   1897 
   1898                 //TBD, lot of other variables to be updated, yet to decide
   1899                 break;
   1900             }
   1901         case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
   1902             {
   1903                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
   1904                 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
   1905                 rc_off_level = (int)pParam->eLevel;
   1906                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1907                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
   1908                                         pParam->eProfile, pParam->eLevel);
   1909                     return false;
   1910                 }
   1911                 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
   1912                     DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
   1913                     return false;
   1914                  }
   1915                 if(!venc_set_ltrmode(1, 1)) {
   1916                    DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
   1917                    return false;
   1918                 }
   1919 
   1920                  // For VP8, hier-p and ltr are mutually exclusive features in firmware
   1921                  // Disable hier-p if ltr is enabled.
   1922                  if (m_codec == OMX_VIDEO_CodingVP8) {
   1923                      DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
   1924                      if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
   1925                         DEBUG_PRINT_ERROR("Disabling Hier P count failed");
   1926                      }
   1927                  }
   1928 
   1929                 break;
   1930             }
   1931             case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
   1932             {
   1933                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
   1934                 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
   1935                 rc_off_level = (int)pParam->eLevel;
   1936                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1937                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
   1938                                         pParam->eProfile, pParam->eLevel);
   1939                     return false;
   1940                 }
   1941                 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
   1942                     DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
   1943 
   1944                 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
   1945                 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
   1946                 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
   1947                     DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1948                     return false;
   1949                 }
   1950                 break;
   1951             }
   1952         case OMX_IndexParamVideoIntraRefresh:
   1953             {
   1954                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
   1955                 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
   1956                     (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
   1957 
   1958                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1959                     if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
   1960                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
   1961                         return false;
   1962                     }
   1963                 } else {
   1964                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
   1965                 }
   1966 
   1967                 break;
   1968             }
   1969         case OMX_IndexParamVideoErrorCorrection:
   1970             {
   1971                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
   1972                 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
   1973                     (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
   1974 
   1975                 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1976                     if (venc_set_error_resilience(error_resilience) == false) {
   1977                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
   1978                         return false;
   1979                     }
   1980                 } else {
   1981                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
   1982                 }
   1983 
   1984                 break;
   1985             }
   1986         case OMX_IndexParamVideoProfileLevelCurrent:
   1987             {
   1988                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
   1989                 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
   1990                     (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   1991 
   1992                 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1993                     m_profile_set = false;
   1994                     m_level_set = false;
   1995                     rc_off_level = (int)profile_level->eLevel;
   1996                     if (!venc_set_profile_level (profile_level->eProfile,
   1997                                 profile_level->eLevel)) {
   1998                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
   1999                         return false;
   2000                     }
   2001                 } else {
   2002                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
   2003                 }
   2004 
   2005                 break;
   2006             }
   2007         case OMX_IndexParamVideoQuantization:
   2008             {
   2009                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
   2010                 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
   2011                     (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
   2012                 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   2013                     if (venc_set_session_qp (session_qp->nQpI,
   2014                                 session_qp->nQpP,
   2015                                 session_qp->nQpB) == false) {
   2016                         DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
   2017                         return false;
   2018                     }
   2019                 } else {
   2020                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
   2021                 }
   2022 
   2023                 break;
   2024             }
   2025         case QOMX_IndexParamVideoInitialQp:
   2026             {
   2027                 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
   2028                     (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
   2029                  if (initqp->bEnableInitQp) {
   2030                     DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
   2031                     if(venc_enable_initial_qp(initqp) == false) {
   2032                        DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
   2033                        return OMX_ErrorUnsupportedSetting;
   2034                      }
   2035                  } else
   2036                     DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
   2037                 break;
   2038             }
   2039         case OMX_QcomIndexParamVideoQPRange:
   2040             {
   2041                 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
   2042                 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
   2043                     (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
   2044 
   2045                 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   2046                     if(venc_set_session_qp_range (session_qp_range->minQP,
   2047                                 session_qp_range->maxQP) == false) {
   2048                         DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
   2049                             (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
   2050                         return false;
   2051                     } else {
   2052                         session_qp_values.minqp = session_qp_range->minQP;
   2053                         session_qp_values.maxqp = session_qp_range->maxQP;
   2054                     }
   2055                 } else {
   2056                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
   2057                 }
   2058 
   2059                 break;
   2060             }
   2061         case OMX_QcomIndexEnableSliceDeliveryMode:
   2062             {
   2063                 QOMX_EXTNINDEX_PARAMTYPE* pParam =
   2064                     (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
   2065 
   2066                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
   2067                     if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
   2068                         DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
   2069                         return OMX_ErrorUnsupportedSetting;
   2070                     }
   2071                 } else {
   2072                     DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
   2073                             "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
   2074                     return OMX_ErrorBadPortIndex;
   2075                 }
   2076 
   2077                 break;
   2078             }
   2079         case OMX_ExtraDataFrameDimension:
   2080             {
   2081                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension");
   2082                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
   2083 
   2084                 if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) {
   2085                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed");
   2086                     return false;
   2087                 }
   2088 
   2089                 extradata = true;
   2090                 break;
   2091             }
   2092         case OMX_ExtraDataVideoEncoderSliceInfo:
   2093             {
   2094                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
   2095                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
   2096 
   2097                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
   2098                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
   2099                     return false;
   2100                 }
   2101 
   2102                 extradata = true;
   2103                 break;
   2104             }
   2105         case OMX_ExtraDataVideoEncoderMBInfo:
   2106             {
   2107                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
   2108                 OMX_BOOL extra_data =  *(OMX_BOOL *)(paramData);
   2109 
   2110                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
   2111                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
   2112                     return false;
   2113                 }
   2114 
   2115                 extradata = true;
   2116                 break;
   2117             }
   2118         case OMX_QcomIndexParamSequenceHeaderWithIDR:
   2119             {
   2120                 PrependSPSPPSToIDRFramesParams * pParam =
   2121                     (PrependSPSPPSToIDRFramesParams *)paramData;
   2122 
   2123                 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
   2124                 if(venc_set_inband_video_header(pParam->bEnable) == false) {
   2125                     DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
   2126                     return OMX_ErrorUnsupportedSetting;
   2127                 }
   2128 
   2129                 break;
   2130             }
   2131         case OMX_QcomIndexParamH264AUDelimiter:
   2132             {
   2133                 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
   2134                     (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
   2135 
   2136                 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
   2137                 if(venc_set_au_delimiter(pParam->bEnable) == false) {
   2138                     DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
   2139                     return OMX_ErrorUnsupportedSetting;
   2140                 }
   2141 
   2142                 break;
   2143             }
   2144         case OMX_QcomIndexParamMBIStatisticsMode:
   2145             {
   2146                 OMX_QOMX_VIDEO_MBI_STATISTICS * pParam =
   2147                     (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData;
   2148 
   2149                 DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType);
   2150                 if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) {
   2151                     DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed");
   2152                     return OMX_ErrorUnsupportedSetting;
   2153                 }
   2154 
   2155                 break;
   2156             }
   2157 
   2158         case OMX_QcomIndexConfigH264EntropyCodingCabac:
   2159             {
   2160                 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam =
   2161                     (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData;
   2162 
   2163                 DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac);
   2164                 if(venc_set_entropy_config (pParam->bCabac, 0) == false) {
   2165                     DEBUG_PRINT_ERROR("ERROR: set Entropy failed");
   2166                     return OMX_ErrorUnsupportedSetting;
   2167                 }
   2168 
   2169                 break;
   2170             }
   2171 
   2172          case OMX_QcomIndexHierarchicalStructure:
   2173            {
   2174                QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
   2175                    (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
   2176 
   2177                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
   2178                     if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
   2179                         DEBUG_PRINT_ERROR("Setting Hier P count failed");
   2180                         return false;
   2181                     }
   2182                 } else {
   2183                     DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
   2184                     return false;
   2185                 }
   2186 
   2187                 // For VP8, hier-p and ltr are mutually exclusive features in firmware
   2188                 // Disable ltr if hier-p is enabled.
   2189                 if (m_codec == OMX_VIDEO_CodingVP8) {
   2190                     DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
   2191                     if(!venc_set_ltrmode(0, 1)) {
   2192                          DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
   2193                      }
   2194                 }
   2195                 break;
   2196            }
   2197         case OMX_QcomIndexParamPerfLevel:
   2198             {
   2199                 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
   2200                         (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
   2201                 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
   2202                 if (!venc_set_perf_level(pParam->ePerfLevel)) {
   2203                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
   2204                     return false;
   2205                 } else {
   2206                     performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
   2207                 }
   2208                 break;
   2209             }
   2210         case OMX_QcomIndexParamH264VUITimingInfo:
   2211             {
   2212                 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
   2213                         (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
   2214                 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
   2215                 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
   2216                     DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
   2217                     return false;
   2218                 } else {
   2219                     vui_timing_info.enabled = (unsigned int) pParam->bEnable;
   2220                 }
   2221                 break;
   2222             }
   2223         case OMX_QTIIndexParamVQZIPSEIType:
   2224             {
   2225                 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam =
   2226                         (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
   2227                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
   2228                 if(venc_set_vqzip_sei_type(pParam->bEnable) == false) {
   2229                     DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable);
   2230                     return false;
   2231                 }
   2232                 break;
   2233             }
   2234         case OMX_QcomIndexParamPeakBitrate:
   2235             {
   2236                 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
   2237                         (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
   2238                 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
   2239                 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
   2240                     DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
   2241                     return false;
   2242                 } else {
   2243                     peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
   2244                 }
   2245                 break;
   2246             }
   2247        case OMX_QcomIndexParamSetMVSearchrange:
   2248             {
   2249                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
   2250                is_searchrange_set = true;
   2251                if (!venc_set_searchrange()) {
   2252                    DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
   2253                    return false;
   2254                }
   2255             }
   2256             break;
   2257         case OMX_QcomIndexParamVideoLTRCount:
   2258             {
   2259                 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
   2260                 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
   2261                         (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
   2262                 if (pParam->nCount > 0) {
   2263                     if (venc_set_ltrmode(1, pParam->nCount) == false) {
   2264                         DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
   2265                         return false;
   2266                     }
   2267                 } else {
   2268                     if (venc_set_ltrmode(0, 0) == false) {
   2269                         DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
   2270                         return false;
   2271                     }
   2272                 }
   2273                 break;
   2274             }
   2275         case OMX_QcomIndexParamVideoHybridHierpMode:
   2276             {
   2277                 if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) {
   2278                      DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
   2279                      return false;
   2280                 }
   2281                 break;
   2282             }
   2283         case OMX_QcomIndexParamBatchSize:
   2284             {
   2285                 OMX_PARAM_U32TYPE* pParam =
   2286                     (OMX_PARAM_U32TYPE*)paramData;
   2287 
   2288                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
   2289                     DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
   2290                             " on output port");
   2291                     return OMX_ErrorUnsupportedSetting;
   2292                 }
   2293 
   2294                 if (!venc_set_batch_size(pParam->nU32)) {
   2295                      DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32);
   2296                      return OMX_ErrorUnsupportedSetting;
   2297                 }
   2298                 break;
   2299             }
   2300         case OMX_QcomIndexParamVencAspectRatio:
   2301             {
   2302                 if (!venc_set_aspectratio(paramData)) {
   2303                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
   2304                     return OMX_ErrorUnsupportedSetting;
   2305                 }
   2306                 break;
   2307             }
   2308         case OMX_QTIIndexParamVideoEnableRoiInfo:
   2309             {
   2310                 struct v4l2_control control;
   2311                 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
   2312                         m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
   2313                     DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
   2314                     return OMX_ErrorUnsupportedSetting;
   2315                 }
   2316                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   2317                 control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP;
   2318                 DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo");
   2319                 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   2320                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
   2321                     return OMX_ErrorUnsupportedSetting;
   2322                 }
   2323                 break;
   2324             }
   2325         case OMX_IndexParamAndroidVideoTemporalLayering:
   2326             {
   2327                 if (venc_set_temporal_layers(
   2328                         (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
   2329                     DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
   2330                     return false;
   2331                 }
   2332                 break;
   2333             }
   2334         case OMX_QTIIndexParamEnableAVTimerTimestamps:
   2335             {
   2336                 QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE *)paramData;
   2337                 mUseAVTimerTimestamps = pParam->bEnable == OMX_TRUE;
   2338                 DEBUG_PRINT_INFO("AVTimer timestamps enabled");
   2339                 break;
   2340             }
   2341         case OMX_IndexParamVideoSliceFMO:
   2342         default:
   2343             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
   2344                     index);
   2345             break;
   2346             //case
   2347     }
   2348 
   2349     return true;
   2350 }
   2351 
   2352 bool venc_dev::venc_check_valid_config()
   2353 {
   2354    if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] &&
   2355        ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) ||
   2356        (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) {
   2357         DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases");
   2358         DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled");
   2359         DEBUG_PRINT_ERROR("For H265 : When Hier P enabled");
   2360         return false;
   2361     }
   2362    return true;
   2363 }
   2364 
   2365 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
   2366 {
   2367 
   2368     DEBUG_PRINT_LOW("Inside venc_set_config");
   2369 
   2370     if(!venc_check_valid_config()) {
   2371         DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration");
   2372         return false;
   2373     }
   2374 
   2375     switch ((int)index) {
   2376         case OMX_IndexConfigVideoBitrate:
   2377             {
   2378                 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
   2379                     configData;
   2380                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
   2381 
   2382                 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   2383                     if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
   2384                         DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
   2385                         return false;
   2386                     }
   2387                 } else {
   2388                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
   2389                 }
   2390 
   2391                 break;
   2392             }
   2393         case OMX_IndexConfigVideoFramerate:
   2394             {
   2395                 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
   2396                     configData;
   2397                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
   2398 
   2399                 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   2400                     if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
   2401                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
   2402                         return false;
   2403                     }
   2404                 } else {
   2405                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
   2406                 }
   2407 
   2408                 break;
   2409             }
   2410         case QOMX_IndexConfigVideoIntraperiod:
   2411             {
   2412                 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
   2413                 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
   2414                     (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
   2415 
   2416                 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   2417                     if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
   2418                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   2419                         return false;
   2420                     }
   2421                 }
   2422 
   2423                 break;
   2424             }
   2425         case OMX_IndexConfigVideoIntraVOPRefresh:
   2426             {
   2427                 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
   2428                     configData;
   2429                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
   2430 
   2431                 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   2432                     if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
   2433                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
   2434                         return false;
   2435                     }
   2436                 } else {
   2437                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
   2438                 }
   2439 
   2440                 break;
   2441             }
   2442         case OMX_IndexConfigCommonRotate:
   2443             {
   2444                 OMX_CONFIG_ROTATIONTYPE *config_rotation =
   2445                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
   2446                 OMX_U32 nFrameWidth;
   2447                 if (!config_rotation) {
   2448                    return false;
   2449                 }
   2450                 if (true == deinterlace_enabled) {
   2451                     DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
   2452                     return false;
   2453                 }
   2454                 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
   2455                 nFrameWidth = m_sVenc_cfg.dvs_width;
   2456                 m_sVenc_cfg.dvs_width  = m_sVenc_cfg.dvs_height;
   2457                 m_sVenc_cfg.dvs_height = nFrameWidth;
   2458 
   2459                 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
   2460                     DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
   2461                     return false;
   2462                 }
   2463 
   2464                 break;
   2465             }
   2466         case OMX_IndexConfigVideoAVCIntraPeriod:
   2467             {
   2468                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
   2469                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
   2470 
   2471                 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
   2472                         == false) {
   2473                     DEBUG_PRINT_ERROR("ERROR: Setting "
   2474                             "OMX_IndexConfigVideoAVCIntraPeriod failed");
   2475                     return false;
   2476                 }
   2477                 break;
   2478             }
   2479         case OMX_IndexConfigCommonDeinterlace:
   2480             {
   2481                 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
   2482                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
   2483                 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   2484                     if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
   2485                         m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
   2486                     {
   2487                         DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
   2488                         return false;
   2489                     }
   2490                     if(venc_set_deinterlace(deinterlace->nEnable) == false) {
   2491                         DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
   2492                         return false;
   2493                     }
   2494                 } else {
   2495                 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
   2496                 }
   2497                 break;
   2498             }
   2499         case OMX_IndexConfigVideoVp8ReferenceFrame:
   2500             {
   2501                 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
   2502                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
   2503                 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
   2504                         (vp8refframe->bUseGoldenFrame)) {
   2505                     if(venc_set_useltr(0x1) == false) {
   2506                         DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
   2507                         return false;
   2508                     }
   2509                 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
   2510                         (vp8refframe->bGoldenFrameRefresh)) {
   2511                     if(venc_set_markltr(0x1) == false) {
   2512                         DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
   2513                         return false;
   2514                     }
   2515                 } else {
   2516                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
   2517                 }
   2518                 break;
   2519             }
   2520         case OMX_QcomIndexConfigVideoLTRUse:
   2521             {
   2522                 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
   2523                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
   2524                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
   2525                     if (venc_set_useltr(pParam->nID) == false) {
   2526                         DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
   2527                         return false;
   2528                     }
   2529                 } else {
   2530                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
   2531                 }
   2532                 break;
   2533             }
   2534         case OMX_QcomIndexConfigVideoLTRMark:
   2535             {
   2536                 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
   2537                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
   2538                 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
   2539                     if (venc_set_markltr(pParam->nID) == false) {
   2540                         DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
   2541                         return false;
   2542                     }
   2543                 }  else {
   2544                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
   2545                 }
   2546                 break;
   2547             }
   2548         case OMX_QcomIndexConfigPerfLevel:
   2549             {
   2550                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   2551                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   2552                 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
   2553                 if (!venc_set_perf_level(perf->ePerfLevel)) {
   2554                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
   2555                     return false;
   2556                 } else {
   2557                     performance_level.perflevel = (unsigned int) perf->ePerfLevel;
   2558                 }
   2559                 break;
   2560             }
   2561         case OMX_QcomIndexConfigVideoVencPerfMode:
   2562             {
   2563                 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
   2564                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
   2565                 if (venc_set_perf_mode(pParam->nPerfMode) == false) {
   2566                     DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
   2567                     return false;
   2568                 }
   2569                 break;
   2570             }
   2571         case OMX_QcomIndexConfigNumHierPLayers:
   2572             {
   2573                 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam =
   2574                     (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData;
   2575                 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers");
   2576                 if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) {
   2577                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers");
   2578                     return false;
   2579                 }
   2580                 break;
   2581             }
   2582         case OMX_QcomIndexConfigBaseLayerId:
   2583             {
   2584                 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
   2585                     (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
   2586                 if (venc_set_baselayerid(pParam->nPID) == false) {
   2587                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
   2588                     return OMX_ErrorUnsupportedSetting;
   2589                 }
   2590                 break;
   2591             }
   2592         case OMX_IndexParamAndroidVideoTemporalLayering:
   2593             {
   2594                 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
   2595                 return false;
   2596             }
   2597         case OMX_QcomIndexConfigQp:
   2598             {
   2599                 OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
   2600                     (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
   2601                 if (venc_set_qp(pParam->nQP) == false) {
   2602                     DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
   2603                     return OMX_ErrorUnsupportedSetting;
   2604                 }
   2605                 break;
   2606             }
   2607         case OMX_IndexConfigPriority:
   2608             {
   2609                 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
   2610                 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
   2611                 if (!venc_set_priority(priority->nU32)) {
   2612                     DEBUG_PRINT_ERROR("Failed to set priority");
   2613                     return false;
   2614                 }
   2615                 sess_priority.priority = priority->nU32;
   2616                 break;
   2617             }
   2618         case OMX_IndexConfigOperatingRate:
   2619             {
   2620                 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
   2621                 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
   2622                 if (!venc_set_operatingrate(rate->nU32)) {
   2623                     DEBUG_PRINT_ERROR("Failed to set operating rate");
   2624                     return false;
   2625                 }
   2626                 break;
   2627             }
   2628         case OMX_QTIIndexConfigVideoRoiInfo:
   2629             {
   2630                 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
   2631                     DEBUG_PRINT_ERROR("Failed to set ROI QP info");
   2632                     return false;
   2633                 }
   2634                 break;
   2635             }
   2636         case OMX_IndexConfigAndroidIntraRefresh:
   2637             {
   2638                 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
   2639                 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
   2640 
   2641                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   2642                     OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16);
   2643                     OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod;
   2644 
   2645                     if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
   2646                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
   2647                         return false;
   2648                     }
   2649                 } else {
   2650                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
   2651                 }
   2652                 break;
   2653             }
   2654         case OMX_QTIIndexConfigDescribeColorAspects:
   2655             {
   2656                 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   2657 
   2658                 OMX_U32 color_space = MSM_VIDC_BT601_6_625;
   2659                 OMX_U32 full_range = 0;
   2660                 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
   2661                 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
   2662 
   2663                 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
   2664                     case ColorAspects::PrimariesBT709_5:
   2665                         color_space = MSM_VIDC_BT709_5;
   2666                         break;
   2667                     case ColorAspects::PrimariesBT470_6M:
   2668                         color_space = MSM_VIDC_BT470_6_M;
   2669                         break;
   2670                     case ColorAspects::PrimariesBT601_6_625:
   2671                         color_space = MSM_VIDC_BT601_6_625;
   2672                         break;
   2673                     case ColorAspects::PrimariesBT601_6_525:
   2674                         color_space = MSM_VIDC_BT601_6_525;
   2675                         break;
   2676                     case ColorAspects::PrimariesGenericFilm:
   2677                         color_space = MSM_VIDC_GENERIC_FILM;
   2678                         break;
   2679                     case ColorAspects::PrimariesBT2020:
   2680                         color_space = MSM_VIDC_BT2020;
   2681                         break;
   2682                     default:
   2683                         color_space = MSM_VIDC_BT601_6_625;
   2684                         //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
   2685                         break;
   2686                 }
   2687                 switch((ColorAspects::Range)params->sAspects.mRange) {
   2688                     case ColorAspects::RangeFull:
   2689                         full_range = 1;
   2690                         break;
   2691                     case ColorAspects::RangeLimited:
   2692                         full_range = 0;
   2693                         break;
   2694                     default:
   2695                         break;
   2696                 }
   2697                 switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
   2698                     case ColorAspects::TransferSMPTE170M:
   2699                         transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
   2700                         break;
   2701                     case ColorAspects::TransferUnspecified:
   2702                         transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
   2703                         break;
   2704                     case ColorAspects::TransferGamma22:
   2705                         transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
   2706                         break;
   2707                     case ColorAspects::TransferGamma28:
   2708                         transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
   2709                         break;
   2710                     case ColorAspects::TransferSMPTE240M:
   2711                         transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
   2712                         break;
   2713                     case ColorAspects::TransferLinear:
   2714                         transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
   2715                         break;
   2716                     case ColorAspects::TransferXvYCC:
   2717                         transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
   2718                         break;
   2719                     case ColorAspects::TransferBT1361:
   2720                         transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
   2721                         break;
   2722                     case ColorAspects::TransferSRGB:
   2723                         transfer_chars = MSM_VIDC_TRANSFER_SRGB;
   2724                         break;
   2725                     default:
   2726                         //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
   2727                         transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
   2728                         break;
   2729                 }
   2730                 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
   2731                     case ColorAspects::MatrixUnspecified:
   2732                         matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
   2733                         break;
   2734                     case ColorAspects::MatrixBT709_5:
   2735                         matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
   2736                         break;
   2737                     case ColorAspects::MatrixBT470_6M:
   2738                         matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
   2739                         break;
   2740                     case ColorAspects::MatrixBT601_6:
   2741                         matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
   2742                         break;
   2743                     case ColorAspects::MatrixSMPTE240M:
   2744                         transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M;
   2745                         break;
   2746                     case ColorAspects::MatrixBT2020:
   2747                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
   2748                         break;
   2749                     case ColorAspects::MatrixBT2020Constant:
   2750                         matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
   2751                         break;
   2752                     default:
   2753                         //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   2754                         matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
   2755                         break;
   2756                 }
   2757                 if (!venc_set_colorspace(color_space, full_range,
   2758                             transfer_chars, matrix_coeffs)) {
   2759 
   2760                     DEBUG_PRINT_ERROR("Failed to set operating rate");
   2761                     return false;
   2762                 }
   2763                 break;
   2764             }
   2765         default:
   2766             DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
   2767             break;
   2768     }
   2769 
   2770     return true;
   2771 }
   2772 
   2773 unsigned venc_dev::venc_stop( void)
   2774 {
   2775     struct venc_msg venc_msg;
   2776     struct v4l2_requestbuffers bufreq;
   2777     int rc = 0, ret = 0;
   2778 
   2779     if (!stopped) {
   2780         enum v4l2_buf_type cap_type;
   2781 
   2782         if (streaming[OUTPUT_PORT]) {
   2783             cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2784             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
   2785 
   2786             if (rc) {
   2787                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
   2788                         cap_type, rc);
   2789             } else
   2790                 streaming[OUTPUT_PORT] = false;
   2791 
   2792             DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
   2793             bufreq.memory = V4L2_MEMORY_USERPTR;
   2794             bufreq.count = 0;
   2795             bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2796             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
   2797 
   2798             if (ret) {
   2799                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
   2800                 return false;
   2801             }
   2802         }
   2803 
   2804         if (!rc && streaming[CAPTURE_PORT]) {
   2805             cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2806             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
   2807 
   2808             if (rc) {
   2809                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
   2810                         cap_type, rc);
   2811             } else
   2812                 streaming[CAPTURE_PORT] = false;
   2813 
   2814             DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
   2815             bufreq.memory = V4L2_MEMORY_USERPTR;
   2816             bufreq.count = 0;
   2817             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2818             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
   2819 
   2820             if (ret) {
   2821                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
   2822                 return false;
   2823             }
   2824         }
   2825 
   2826         if (!rc && !ret) {
   2827             venc_stop_done();
   2828             stopped = 1;
   2829             /*set flag to re-configure when started again*/
   2830             resume_in_stopped = 1;
   2831 
   2832         }
   2833     }
   2834 
   2835     return rc;
   2836 }
   2837 
   2838 unsigned venc_dev::venc_pause(void)
   2839 {
   2840     pthread_mutex_lock(&pause_resume_mlock);
   2841     paused = true;
   2842     pthread_mutex_unlock(&pause_resume_mlock);
   2843     return 0;
   2844 }
   2845 
   2846 unsigned venc_dev::venc_resume(void)
   2847 {
   2848     pthread_mutex_lock(&pause_resume_mlock);
   2849     paused = false;
   2850     pthread_mutex_unlock(&pause_resume_mlock);
   2851 
   2852     return pthread_cond_signal(&pause_resume_cond);
   2853 }
   2854 
   2855 unsigned venc_dev::venc_start_done(void)
   2856 {
   2857     struct venc_msg venc_msg;
   2858     venc_msg.msgcode = VEN_MSG_START;
   2859     venc_msg.statuscode = VEN_S_SUCCESS;
   2860     venc_handle->async_message_process(venc_handle,&venc_msg);
   2861     return 0;
   2862 }
   2863 
   2864 unsigned venc_dev::venc_stop_done(void)
   2865 {
   2866     struct venc_msg venc_msg;
   2867     venc_msg.msgcode=VEN_MSG_STOP;
   2868     venc_msg.statuscode=VEN_S_SUCCESS;
   2869     venc_handle->async_message_process(venc_handle,&venc_msg);
   2870     return 0;
   2871 }
   2872 
   2873 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
   2874 {
   2875     async_thread_created = true;
   2876     m_tid=tid;
   2877     return 0;
   2878 }
   2879 
   2880 bool venc_dev::venc_set_vqzip_defaults()
   2881 {
   2882     struct v4l2_control control;
   2883     int rc = 0, num_mbs_per_frame;
   2884 
   2885     num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width;
   2886 
   2887     switch (num_mbs_per_frame) {
   2888     case OMX_CORE_720P_WIDTH  * OMX_CORE_720P_HEIGHT:
   2889     case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT:
   2890     case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT:
   2891     case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT:
   2892         break;
   2893     default:
   2894         DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu",
   2895             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
   2896         return false;
   2897     }
   2898 
   2899     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
   2900     control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
   2901     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2902     if (rc)
   2903         DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP");
   2904     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
   2905     control.value = INT_MAX;
   2906 
   2907     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2908     if (rc)
   2909         DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP");
   2910 
   2911     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
   2912     control.value = 0;
   2913 
   2914     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2915     if (rc)
   2916         DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP");
   2917 
   2918     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
   2919     control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY;
   2920 
   2921     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2922     if (rc)
   2923         DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP");
   2924 
   2925     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
   2926     control.value = 1;
   2927 
   2928     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2929     if (rc)
   2930         DEBUG_PRINT_ERROR("Failed to set IDR period for VQZIP");
   2931 
   2932     return true;
   2933 }
   2934 
   2935 
   2936 unsigned venc_dev::venc_start(void)
   2937 {
   2938     enum v4l2_buf_type buf_type;
   2939     int ret, r;
   2940     struct v4l2_control control;
   2941 
   2942     memset(&control, 0, sizeof(control));
   2943 
   2944     DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
   2945             __func__);
   2946     m_level_set = false;
   2947 
   2948     if (!venc_set_profile_level(0, 0)) {
   2949         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
   2950                 __func__);
   2951     } else {
   2952         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
   2953                 __func__, codec_profile.profile, profile_level.level);
   2954     }
   2955 
   2956     if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults())
   2957         return 1;
   2958 
   2959     // disable B-frames for realtime high-resolution/fps usecases for power considerations
   2960     if (intra_period.num_bframes &&
   2961             sess_priority.priority == 0 /*realtime*/ &&
   2962             (((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) > (1920 * 1088)) ||
   2963             (operating_rate >= 60 << 16))) {
   2964         intra_period.num_pframes += (intra_period.num_bframes + 1);
   2965         intra_period.num_bframes = 0;
   2966         if (venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
   2967             DEBUG_PRINT_INFO("Disabling B frames: res = %lux%lu : operating-rate = %u frames/sec",
   2968                     m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, operating_rate >> 16);
   2969         } else {
   2970             DEBUG_PRINT_ERROR("Failed to disable B frames!");
   2971         }
   2972     }
   2973 
   2974     // re-configure the temporal layers as RC-mode and key-frame interval
   2975     // might have changed since the client last configured the layers.
   2976     if (temporal_layers_config.nPLayers) {
   2977         if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
   2978             DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
   2979         } else {
   2980             // request buffers on capture port again since internal (scratch)-
   2981             // buffer requirements may change (i.e if we switch from non-hybrid
   2982             // to hybrid mode and vice-versa)
   2983             struct v4l2_requestbuffers bufreq;
   2984 
   2985             bufreq.memory = V4L2_MEMORY_USERPTR;
   2986             bufreq.count = m_sOutput_buff_property.actualcount;
   2987             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2988             if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
   2989                 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
   2990             }
   2991         }
   2992     }
   2993 
   2994     venc_config_print();
   2995 
   2996     if(resume_in_stopped){
   2997         /*set buffercount when restarted*/
   2998         venc_reconfig_reqbufs();
   2999         resume_in_stopped = 0;
   3000     }
   3001 
   3002     /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
   3003     if (slice_mode.enable && multislice.mslice_size &&
   3004             (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
   3005         DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
   3006                 (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
   3007                 MAX_SUPPORTED_SLICES_PER_FRAME);
   3008         return 1;
   3009     }
   3010 
   3011     buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3012     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   3013     ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
   3014 
   3015     if (ret)
   3016         return 1;
   3017 
   3018     streaming[CAPTURE_PORT] = true;
   3019 
   3020     control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
   3021     control.value = 1;
   3022     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3023     if (ret) {
   3024         DEBUG_PRINT_ERROR("failed to request seq header");
   3025         return 1;
   3026     }
   3027 
   3028 
   3029     stopped = 0;
   3030     return 0;
   3031 }
   3032 
   3033 inline const char* hiermode_string(int val)
   3034 {
   3035     switch(val)
   3036     {
   3037     case HIER_NONE:
   3038         return "No Hier";
   3039     case HIER_P:
   3040         return "Hier-P";
   3041     case HIER_B:
   3042         return "Hier-B";
   3043     case HIER_P_HYBRID:
   3044         return "Hybrid Hier-P";
   3045     default:
   3046         return "No hier";
   3047     }
   3048 }
   3049 
   3050 inline const char* bitrate_type_string(int val)
   3051 {
   3052     switch(val)
   3053     {
   3054     case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE:
   3055         return "CUMULATIVE";
   3056     case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE:
   3057         return "LAYER WISE";
   3058     default:
   3059         return "Unknown Bitrate Type";
   3060     }
   3061 }
   3062 
   3063 static const char *codec_as_string(unsigned long codec) {
   3064     switch (codec) {
   3065     case V4L2_PIX_FMT_H264:
   3066         return "H264";
   3067     case V4L2_PIX_FMT_MPEG4:
   3068         return "MPEG4";
   3069     case V4L2_PIX_FMT_H263:
   3070         return "H263";
   3071     case V4L2_PIX_FMT_HEVC:
   3072         return "HEVC";
   3073     case V4L2_PIX_FMT_VP8:
   3074         return "VP8";
   3075     default:
   3076         return "UNKOWN";
   3077     }
   3078 }
   3079 
   3080 void venc_dev::venc_config_print()
   3081 {
   3082 
   3083     DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
   3084             codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
   3085 
   3086     DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
   3087             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
   3088             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
   3089 
   3090     DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
   3091             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
   3092             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
   3093 
   3094     DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
   3095             color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
   3096 
   3097     DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
   3098             bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
   3099 
   3100     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
   3101             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
   3102 
   3103     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
   3104             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
   3105 
   3106     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
   3107             session_qp_values.minqp, session_qp_values.maxqp);
   3108 
   3109     DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
   3110             voptimecfg.voptime_resolution, multislice.mslice_mode,
   3111             multislice.mslice_size);
   3112 
   3113     DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
   3114             entropy.longentropysel, entropy.cabacmodel);
   3115 
   3116     DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
   3117             dbkfilter.db_mode, dbkfilter.slicealpha_offset,
   3118             dbkfilter.slicebeta_offset);
   3119 
   3120     DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
   3121             intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
   3122 
   3123     DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
   3124             ltrinfo.enabled, ltrinfo.count);
   3125 
   3126     if (temporal_layers_config.nPLayers) {
   3127         DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
   3128                 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
   3129                 intra_period.num_pframes + intra_period.num_bframes + 1);
   3130 
   3131         for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid
   3132                 && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) {
   3133             DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%",
   3134                     l, temporal_layers_config.nTemporalLayerBitrateFraction[l]);
   3135         }
   3136     } else {
   3137 
   3138         DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
   3139                 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
   3140 
   3141         DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d",
   3142                 hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer);
   3143 
   3144         DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d",
   3145                 hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1],
   3146                 hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3],
   3147                 hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]);
   3148     }
   3149 
   3150     DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
   3151 
   3152     DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
   3153 
   3154     DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
   3155 
   3156     DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
   3157 
   3158     DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
   3159 }
   3160 
   3161 bool venc_dev::venc_reconfig_reqbufs()
   3162 {
   3163     struct v4l2_requestbuffers bufreq;
   3164 
   3165     bufreq.memory = V4L2_MEMORY_USERPTR;
   3166     bufreq.count = m_sInput_buff_property.actualcount;
   3167     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3168     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   3169             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
   3170             return false;
   3171     }
   3172 
   3173     bufreq.memory = V4L2_MEMORY_USERPTR;
   3174     bufreq.count = m_sOutput_buff_property.actualcount;
   3175     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3176     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
   3177     {
   3178             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
   3179             return false;
   3180     }
   3181     return true;
   3182 }
   3183 
   3184 unsigned venc_dev::venc_flush( unsigned port)
   3185 {
   3186     struct v4l2_encoder_cmd enc;
   3187     DEBUG_PRINT_LOW("in %s", __func__);
   3188 
   3189     enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
   3190     enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
   3191 
   3192     if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
   3193         DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
   3194         return -1;
   3195     }
   3196 
   3197     return 0;
   3198 
   3199 }
   3200 
   3201 //allocating I/P memory from pmem and register with the device
   3202 
   3203 
   3204 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
   3205 {
   3206 
   3207     struct pmem *pmem_tmp;
   3208     struct v4l2_buffer buf;
   3209     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   3210     int rc = 0;
   3211     unsigned int extra_idx;
   3212 
   3213     pmem_tmp = (struct pmem *)buf_addr;
   3214     DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
   3215 
   3216     if (port == PORT_INDEX_OUT) {
   3217         extra_idx = EXTRADATA_IDX(num_output_planes);
   3218         buf.index = index;
   3219         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3220         buf.memory = V4L2_MEMORY_USERPTR;
   3221         plane[0].length = pmem_tmp->size;
   3222         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
   3223         plane[0].reserved[0] = pmem_tmp->fd;
   3224         plane[0].reserved[1] = 0;
   3225         plane[0].data_offset = pmem_tmp->offset;
   3226         buf.m.planes = plane;
   3227         buf.length = num_output_planes;
   3228 
   3229         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   3230             char *userptr;
   3231             int fd;
   3232             unsigned offset;
   3233             ssize_t size;
   3234             int rc = mOutputExtradata.peek(index, &userptr, &fd, &offset, &size);
   3235             if (rc != OMX_ErrorNone) {
   3236                 DEBUG_PRINT_ERROR("Unable to get extradata memory 2");
   3237                 return rc;
   3238             }
   3239             plane[extra_idx].length = size;
   3240             plane[extra_idx].m.userptr = (unsigned long)userptr;
   3241 #ifdef USE_ION
   3242             plane[extra_idx].reserved[0] = fd;
   3243 #endif
   3244             plane[extra_idx].reserved[1] = offset;
   3245             plane[extra_idx].data_offset = 0;
   3246         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   3247             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   3248             return OMX_ErrorBadParameter;
   3249         }
   3250 
   3251         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
   3252 
   3253         if (rc)
   3254             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
   3255     } else if (port == PORT_INDEX_IN) {
   3256             DEBUG_PRINT_LOW("No need to call VIDIOC_PREPARE_BUF on input port");
   3257     } else {
   3258         DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
   3259         return false;
   3260     }
   3261 
   3262     return true;
   3263 }
   3264 
   3265 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
   3266 {
   3267     struct pmem *pmem_tmp;
   3268     struct venc_bufferpayload dev_buffer;
   3269 
   3270     memset(&dev_buffer, 0, sizeof(dev_buffer));
   3271     pmem_tmp = (struct pmem *)buf_addr;
   3272 
   3273     if (port == PORT_INDEX_IN) {
   3274         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   3275         dev_buffer.fd  = pmem_tmp->fd;
   3276         dev_buffer.maped_size = pmem_tmp->size;
   3277         dev_buffer.sz = pmem_tmp->size;
   3278         dev_buffer.offset = pmem_tmp->offset;
   3279         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
   3280                 dev_buffer.pbuffer, \
   3281                 dev_buffer.fd, \
   3282                 dev_buffer.offset, \
   3283                 dev_buffer.maped_size);
   3284 
   3285     } else if (port == PORT_INDEX_OUT) {
   3286         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   3287         dev_buffer.fd  = pmem_tmp->fd;
   3288         dev_buffer.sz = pmem_tmp->size;
   3289         dev_buffer.maped_size = pmem_tmp->size;
   3290         dev_buffer.offset = pmem_tmp->offset;
   3291 
   3292         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
   3293                 dev_buffer.pbuffer, \
   3294                 dev_buffer.fd, \
   3295                 dev_buffer.offset, \
   3296                 dev_buffer.maped_size);
   3297     } else {
   3298         DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
   3299         return false;
   3300     }
   3301 
   3302     return true;
   3303 }
   3304 
   3305 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
   3306         OMX_U32 width, OMX_U32 height)
   3307 {
   3308     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
   3309             y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
   3310             uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
   3311             uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
   3312             src_chroma_offset = width * height;
   3313 
   3314     if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
   3315         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
   3316         //Do chroma first, so that we can convert it in-place
   3317         src_buf += width * height;
   3318         dst_buf += y_stride * y_scanlines;
   3319         for (int line = height / 2 - 1; line >= 0; --line) {
   3320             memmove(dst_buf + line * uv_stride,
   3321                     src_buf + line * width,
   3322                     width);
   3323         }
   3324 
   3325         dst_buf = src_buf = buffer->pBuffer;
   3326         //Copy the Y next
   3327         for (int line = height - 1; line > 0; --line) {
   3328             memmove(dst_buf + line * y_stride,
   3329                     src_buf + line * width,
   3330                     width);
   3331         }
   3332     } else {
   3333         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
   3334                 Insufficient bufferLen=%u v/s Required=%u",
   3335                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
   3336                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
   3337         return false;
   3338     }
   3339 
   3340     return true;
   3341 }
   3342 
   3343 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
   3344 {
   3345     if (!perflevel) {
   3346         DEBUG_PRINT_ERROR("Null pointer error");
   3347         return false;
   3348     } else {
   3349         *perflevel = performance_level.perflevel;
   3350         return true;
   3351     }
   3352 }
   3353 
   3354 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
   3355 {
   3356     if (!enabled) {
   3357         DEBUG_PRINT_ERROR("Null pointer error");
   3358         return false;
   3359     } else {
   3360         *enabled = vui_timing_info.enabled;
   3361         return true;
   3362     }
   3363 }
   3364 
   3365 bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled)
   3366 {
   3367     if (!enabled) {
   3368         DEBUG_PRINT_ERROR("Null pointer error");
   3369         return false;
   3370     } else {
   3371         *enabled = vqzip_sei_info.enabled;
   3372         return true;
   3373     }
   3374 }
   3375 
   3376 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
   3377 {
   3378     if (!peakbitrate) {
   3379         DEBUG_PRINT_ERROR("Null pointer error");
   3380         return false;
   3381     } else {
   3382         *peakbitrate = peak_bitrate.peakbitrate;
   3383         return true;
   3384     }
   3385 }
   3386 
   3387 bool venc_dev::venc_get_batch_size(OMX_U32 *size)
   3388 {
   3389     if (!size) {
   3390         DEBUG_PRINT_ERROR("Null pointer error");
   3391         return false;
   3392     } else {
   3393         *size = mBatchSize;
   3394         return true;
   3395     }
   3396 }
   3397 
   3398 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
   3399 {
   3400     struct pmem *temp_buffer;
   3401     struct v4l2_buffer buf;
   3402     struct v4l2_requestbuffers bufreq;
   3403     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   3404     int rc = 0, extra_idx;
   3405     struct OMX_BUFFERHEADERTYPE *bufhdr;
   3406     encoder_media_buffer_type * meta_buf = NULL;
   3407     temp_buffer = (struct pmem *)buffer;
   3408 
   3409     memset (&buf, 0, sizeof(buf));
   3410     memset (&plane, 0, sizeof(plane));
   3411 
   3412     if (buffer == NULL) {
   3413         DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
   3414         return false;
   3415     }
   3416 
   3417     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   3418     bufreq.memory = V4L2_MEMORY_USERPTR;
   3419     bufreq.count = m_sInput_buff_property.actualcount;
   3420     bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3421 
   3422     DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
   3423 
   3424     if (pmem_data_buf) {
   3425         DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
   3426         plane[0].m.userptr = (unsigned long)pmem_data_buf;
   3427         plane[0].data_offset = bufhdr->nOffset;
   3428         plane[0].length = bufhdr->nAllocLen;
   3429         plane[0].bytesused = bufhdr->nFilledLen;
   3430     } else {
   3431         // --------------------------------------------------------------------------------------
   3432         // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
   3433         // ---------------------------------------------------------------------------------------
   3434         // Camera-2              1            CameraSource   0              meta-handle
   3435         // Camera-3              1            GrallocSource  0              gralloc-private-handle
   3436         // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
   3437         // CPU (Eg: MediaCodec)  0            --             0              bufhdr
   3438         // ---------------------------------------------------------------------------------------
   3439         if (metadatamode) {
   3440             plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
   3441             meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
   3442 
   3443             if (!meta_buf) {
   3444                 //empty EOS buffer
   3445                 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
   3446                     plane[0].data_offset = bufhdr->nOffset;
   3447                     plane[0].length = bufhdr->nAllocLen;
   3448                     plane[0].bytesused = bufhdr->nFilledLen;
   3449                     DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
   3450                 } else {
   3451                     return false;
   3452                 }
   3453             } else if (!color_format) {
   3454                 int usage = 0;
   3455 
   3456                 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
   3457                     native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
   3458                     if (!hnd) {
   3459                         DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
   3460                         return false;
   3461                     }
   3462 
   3463                     if (!mBatchSize && hnd->numFds + hnd->numInts > 3) {
   3464                         usage = hnd->data[3];
   3465                     } else if (mBatchSize) {
   3466                         usage = BatchInfo::getColorFormatAt(hnd, 0);
   3467                     }
   3468                     if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) {
   3469                         buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
   3470                     }
   3471 
   3472                     if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
   3473                         m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
   3474                         struct v4l2_format fmt;
   3475 
   3476                         memset(&fmt, 0, sizeof(fmt));
   3477                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
   3478                                 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
   3479                             DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
   3480                             DEBUG_PRINT_ERROR(" This leads to unknown color space");
   3481                         }
   3482                         if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
   3483                             if (is_csc_enabled) {
   3484                                 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
   3485                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
   3486                                 venc_set_colorspace(MSM_VIDC_BT709_5, 1,
   3487                                         MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
   3488                             } else {
   3489                                 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
   3490                                         MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
   3491                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
   3492                             }
   3493                         }
   3494                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3495                         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
   3496                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   3497                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   3498                         if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
   3499                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
   3500                         }
   3501                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   3502                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   3503                             DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
   3504                             return false;
   3505                         }
   3506                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   3507                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
   3508                             return false;
   3509                         }
   3510                     }
   3511 
   3512                     // Setting batch mode is sticky. We do not expect camera to change
   3513                     // between batch and normal modes at runtime.
   3514                     if (mBatchSize) {
   3515                         if ((unsigned)hnd->numFds != mBatchSize) {
   3516                             DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
   3517                                     mBatchSize, hnd->numFds);
   3518                             return false;
   3519                         }
   3520 
   3521                         return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
   3522                     }
   3523 
   3524                     if (hnd->numFds + hnd->numInts > 2) {
   3525                         plane[0].data_offset = hnd->data[1];
   3526                         plane[0].length = hnd->data[2];
   3527                         plane[0].bytesused = hnd->data[2];
   3528                     }
   3529                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
   3530                             fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
   3531                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
   3532                     private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
   3533 
   3534                     if (!handle) {
   3535                         DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
   3536                         return false;
   3537                     }
   3538 
   3539                     if (mUseAVTimerTimestamps) {
   3540                         uint64_t avTimerTimestampNs = bufhdr->nTimeStamp * 1000;
   3541                         if (getMetaData(handle, GET_VT_TIMESTAMP, &avTimerTimestampNs) == 0
   3542                                 && avTimerTimestampNs > 0) {
   3543                             bufhdr->nTimeStamp = avTimerTimestampNs / 1000;
   3544                             DEBUG_PRINT_LOW("AVTimer TS : %llu us", (unsigned long long)bufhdr->nTimeStamp);
   3545                         }
   3546                     }
   3547 
   3548                     if (!streaming[OUTPUT_PORT]) {
   3549                         // Moment of truth... actual colorspace is known here..
   3550                         ColorSpace_t colorSpace = ITU_R_601;
   3551                         if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
   3552                             DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
   3553                                     colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   3554                         }
   3555 
   3556                         struct v4l2_format fmt;
   3557                         memset(&fmt, 0, sizeof(fmt));
   3558                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3559 
   3560                         bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
   3561                         if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
   3562                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
   3563                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
   3564                         } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
   3565                             // In case of RGB, conversion to YUV is handled within encoder.
   3566                             // Disregard the Colorspace in gralloc-handle in case of RGB and use
   3567                             //   [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
   3568                             //   [b] 601 for UBWC case     : Venus can convert to 601-LR or FR. use LR for now.
   3569                             colorSpace = ITU_R_601;
   3570                             m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
   3571                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
   3572                         } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
   3573                             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
   3574                             DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
   3575                         }
   3576 
   3577                         // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
   3578                         if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
   3579                             struct v4l2_control control;
   3580                             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
   3581                             control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
   3582                             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   3583                                 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
   3584                             } else {
   3585                                 DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
   3586                                 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
   3587                                 colorSpace = ITU_R_709;
   3588                             }
   3589                         }
   3590 
   3591                         msm_vidc_h264_color_primaries_values primary;
   3592                         msm_vidc_h264_transfer_chars_values transfer;
   3593                         msm_vidc_h264_matrix_coeff_values matrix;
   3594                         OMX_U32 range;
   3595 
   3596                         switch (colorSpace) {
   3597                             case ITU_R_601_FR:
   3598                             {
   3599                                 primary = MSM_VIDC_BT601_6_525;
   3600                                 range = 1; // full
   3601                                 transfer = MSM_VIDC_TRANSFER_601_6_525;
   3602                                 matrix = MSM_VIDC_MATRIX_601_6_525;
   3603 
   3604                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
   3605                                 break;
   3606                             }
   3607                             case ITU_R_709:
   3608                             {
   3609                                 primary = MSM_VIDC_BT709_5;
   3610                                 range = 0; // limited
   3611                                 transfer = MSM_VIDC_TRANSFER_BT709_5;
   3612                                 matrix = MSM_VIDC_MATRIX_BT_709_5;
   3613 
   3614                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
   3615                                 break;
   3616                             }
   3617                             default:
   3618                             {
   3619                                 // 601 or something else ? assume 601
   3620                                 primary = MSM_VIDC_BT601_6_625;
   3621                                 range = 0; //limited
   3622                                 transfer = MSM_VIDC_TRANSFER_601_6_625;
   3623                                 matrix = MSM_VIDC_MATRIX_601_6_625;
   3624 
   3625                                 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
   3626                                 break;
   3627                             }
   3628                         }
   3629                         DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
   3630                                     colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   3631                         venc_set_colorspace(primary, range, transfer, matrix);
   3632 
   3633                         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   3634                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   3635                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   3636                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   3637                             DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat);
   3638                             return false;
   3639                         }
   3640                         if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   3641                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
   3642                             return false;
   3643                         }
   3644                     }
   3645 
   3646                     fd = handle->fd;
   3647                     plane[0].data_offset = 0;
   3648                     plane[0].length = handle->size;
   3649                     plane[0].bytesused = handle->size;
   3650                     DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
   3651                                 ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat);
   3652                 }
   3653             } else {
   3654                 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
   3655                 plane[0].data_offset = bufhdr->nOffset;
   3656                 plane[0].length = bufhdr->nAllocLen;
   3657                 plane[0].bytesused = bufhdr->nFilledLen;
   3658                 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
   3659                         fd, plane[0].bytesused, plane[0].length);
   3660             }
   3661         } else {
   3662             plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
   3663             plane[0].data_offset = bufhdr->nOffset;
   3664             plane[0].length = bufhdr->nAllocLen;
   3665             plane[0].bytesused = bufhdr->nFilledLen;
   3666             DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
   3667                     fd, plane[0].bytesused, plane[0].length);
   3668         }
   3669     }
   3670 
   3671     extra_idx = EXTRADATA_IDX(num_input_planes);
   3672 
   3673     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   3674         char *userptr;
   3675         int fd;
   3676         unsigned offset;
   3677         ssize_t size;
   3678         int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size);
   3679         if (rc != OMX_ErrorNone) {
   3680             DEBUG_PRINT_ERROR("Unable to get extradata memory 1");
   3681             return rc;
   3682         }
   3683         plane[extra_idx].bytesused = 0;
   3684         plane[extra_idx].length = size;
   3685         plane[extra_idx].m.userptr = (unsigned long) userptr;
   3686 #ifdef USE_ION
   3687         plane[extra_idx].reserved[0] = fd;
   3688 #endif
   3689         plane[extra_idx].reserved[1] = offset;
   3690         plane[extra_idx].data_offset = 0;
   3691     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   3692         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
   3693         return false;
   3694     }
   3695 
   3696     if (!streaming[OUTPUT_PORT]) {
   3697         enum v4l2_buf_type buf_type;
   3698         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3699         int ret;
   3700         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
   3701 
   3702         if (ret) {
   3703             DEBUG_PRINT_ERROR("Failed to call streamon");
   3704             if (errno == EBUSY) {
   3705                 hw_overload = true;
   3706             }
   3707             return false;
   3708         } else {
   3709             streaming[OUTPUT_PORT] = true;
   3710         }
   3711     }
   3712 
   3713     buf.index = index;
   3714     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3715     buf.memory = V4L2_MEMORY_USERPTR;
   3716     plane[0].reserved[0] = fd;
   3717     plane[0].reserved[1] = 0;
   3718     buf.m.planes = plane;
   3719     buf.length = num_input_planes;
   3720 
   3721     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
   3722         buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
   3723 
   3724     buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
   3725     buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
   3726     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
   3727 
   3728     if (rc) {
   3729         DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
   3730         return false;
   3731     }
   3732 
   3733     etb++;
   3734 
   3735     if (m_debug.in_buffer_log) {
   3736         venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
   3737     }
   3738 
   3739     return true;
   3740 }
   3741 
   3742 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
   3743 {
   3744     struct v4l2_buffer buf;
   3745     struct v4l2_plane plane;
   3746     int rc = 0;
   3747     struct v4l2_control control;
   3748     encoder_media_buffer_type * meta_buf = NULL;
   3749     native_handle_t *hnd = NULL;
   3750 
   3751     if (bufhdr == NULL) {
   3752         DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
   3753         return false;
   3754     }
   3755 
   3756     bool status = true;
   3757     if (metadatamode) {
   3758         plane.m.userptr = (unsigned long)bufhdr->pBuffer;
   3759         meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
   3760 
   3761         if (!color_format) {
   3762             if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
   3763                 hnd = (native_handle_t*)meta_buf->meta_handle;
   3764                 if (!hnd) {
   3765                     DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
   3766                     return false;
   3767                 } else if (hnd->numFds > kMaxBuffersInBatch) {
   3768                     DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
   3769                             "Max = %d", hnd->numFds, kMaxBuffersInBatch);
   3770                     status = false;
   3771                 }
   3772                 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
   3773             } else {
   3774                 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
   3775                 status = false;
   3776             }
   3777         } else {
   3778             DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
   3779             status = false;
   3780         }
   3781     } else {
   3782         DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
   3783         status = false;
   3784     }
   3785 
   3786     if (status) {
   3787         OMX_TICKS bufTimeStamp = 0ll;
   3788         int numBufs = hnd->numFds;
   3789         int v4l2Ids[kMaxBuffersInBatch] = {-1};
   3790         for (int i = 0; i < numBufs; ++i) {
   3791             v4l2Ids[i] = mBatchInfo.registerBuffer(index);
   3792             if (v4l2Ids[i] < 0) {
   3793                 DEBUG_PRINT_ERROR("Failed to register buffer");
   3794                 // TODO: cleanup the map and purge all slots of current index
   3795                 status = false;
   3796                 break;
   3797             }
   3798         }
   3799         for (int i = 0; i < numBufs; ++i) {
   3800             int v4l2Id = v4l2Ids[i];
   3801 
   3802             memset(&buf, 0, sizeof(buf));
   3803             memset(&plane, 0, sizeof(plane));
   3804 
   3805             DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
   3806             buf.index = (unsigned)v4l2Id;
   3807             buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3808             buf.memory = V4L2_MEMORY_USERPTR;
   3809             plane.reserved[0] = BatchInfo::getFdAt(hnd, i);
   3810             plane.reserved[1] = 0;
   3811             plane.data_offset = BatchInfo::getOffsetAt(hnd, i);
   3812             plane.m.userptr = (unsigned long)meta_buf;
   3813             plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i);
   3814             buf.m.planes = &plane;
   3815             buf.length = 1;
   3816 
   3817             if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
   3818                 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
   3819             if (i != numBufs - 1) {
   3820                 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
   3821                 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
   3822                         i, etb + 1, numBufs);
   3823             }
   3824 
   3825 
   3826             // timestamp differences from camera are in nano-seconds
   3827             bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
   3828 
   3829             DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
   3830                 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp);
   3831             buf.timestamp.tv_sec = bufTimeStamp / 1000000;
   3832             buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
   3833 
   3834             rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
   3835             if (rc) {
   3836                 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
   3837                 return false;
   3838             }
   3839 
   3840             etb++;
   3841         }
   3842     }
   3843 
   3844     if (status && !streaming[OUTPUT_PORT]) {
   3845         enum v4l2_buf_type buf_type;
   3846         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3847         int ret;
   3848         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
   3849         if (ret) {
   3850             DEBUG_PRINT_ERROR("Failed to call streamon");
   3851             if (errno == EBUSY) {
   3852                 hw_overload = true;
   3853             }
   3854             status = false;
   3855         } else {
   3856             streaming[OUTPUT_PORT] = true;
   3857         }
   3858     }
   3859 
   3860     return status;
   3861 }
   3862 
   3863 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
   3864 {
   3865     struct pmem *temp_buffer = NULL;
   3866     struct venc_buffer  frameinfo;
   3867     struct v4l2_buffer buf;
   3868     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   3869     int rc = 0;
   3870     unsigned int extra_idx;
   3871     struct OMX_BUFFERHEADERTYPE *bufhdr;
   3872 
   3873     if (buffer == NULL)
   3874         return false;
   3875 
   3876     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   3877 
   3878     if (pmem_data_buf) {
   3879         DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
   3880         plane[0].m.userptr = (unsigned long)pmem_data_buf;
   3881     } else {
   3882         DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
   3883         plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
   3884     }
   3885 
   3886     memset(&buf, 0, sizeof(buf));
   3887     memset(&plane, 0, sizeof(plane));
   3888 
   3889     buf.index = index;
   3890     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3891     buf.memory = V4L2_MEMORY_USERPTR;
   3892     plane[0].length = bufhdr->nAllocLen;
   3893     plane[0].bytesused = bufhdr->nFilledLen;
   3894     plane[0].reserved[0] = fd;
   3895     plane[0].reserved[1] = 0;
   3896     plane[0].data_offset = bufhdr->nOffset;
   3897     buf.m.planes = plane;
   3898     buf.length = num_output_planes;
   3899     buf.flags = 0;
   3900 
   3901     if (mBatchSize) {
   3902         // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
   3903         // This results in the first batch being of size mBatchSize + 1, but thats good because
   3904         // we need an extra FTB for the codec specific data.
   3905 
   3906         if (!ftb || ftb % mBatchSize) {
   3907             buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
   3908             DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
   3909         }
   3910     }
   3911 
   3912     extra_idx = EXTRADATA_IDX(num_output_planes);
   3913 
   3914     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   3915         char *userptr;
   3916         int fd;
   3917         unsigned offset;
   3918         ssize_t size;
   3919         int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size);
   3920         if (rc != OMX_ErrorNone) {
   3921             DEBUG_PRINT_ERROR("Unable to get extradata memory 0");
   3922             return false;
   3923         }
   3924         plane[extra_idx].bytesused = 0;
   3925         plane[extra_idx].length = size;
   3926         plane[extra_idx].m.userptr = (unsigned long)userptr;
   3927 #ifdef USE_ION
   3928         plane[extra_idx].reserved[0] = fd;
   3929 #endif
   3930         plane[extra_idx].reserved[1] = offset;
   3931         plane[extra_idx].data_offset = 0;
   3932     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   3933         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
   3934         return false;
   3935     }
   3936 
   3937     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
   3938 
   3939     if (rc) {
   3940         DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
   3941         return false;
   3942     }
   3943 
   3944     ftb++;
   3945     return true;
   3946 }
   3947 
   3948 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
   3949 {
   3950     struct v4l2_control control;
   3951 
   3952     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
   3953     if(enable) {
   3954         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
   3955     } else {
   3956         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
   3957     }
   3958 
   3959     DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
   3960     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
   3961         DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
   3962         return false;
   3963     }
   3964     return true;
   3965 }
   3966 
   3967 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
   3968 {
   3969     struct v4l2_control control;
   3970 
   3971     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
   3972     if(enable) {
   3973         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
   3974     } else {
   3975         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
   3976     }
   3977 
   3978     DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
   3979     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
   3980         DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
   3981         return false;
   3982     }
   3983     return true;
   3984 }
   3985 
   3986 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
   3987 {
   3988     struct v4l2_control control;
   3989 
   3990     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
   3991     control.value = mode;
   3992 
   3993     DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
   3994     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
   3995         DEBUG_PRINT_ERROR("Setting MBI mode failed");
   3996         return false;
   3997     }
   3998     return true;
   3999 }
   4000 
   4001 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
   4002 {
   4003     struct v4l2_control sei_control, yuvstats_control;
   4004 
   4005     DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
   4006     sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
   4007     yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   4008 
   4009     if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
   4010         DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
   4011     }
   4012 
   4013     if(enable) {
   4014         sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
   4015         yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
   4016     } else {
   4017         sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
   4018         yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
   4019     }
   4020 
   4021     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
   4022         DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
   4023     }
   4024 
   4025     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
   4026         DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
   4027     }
   4028 #ifdef _VQZIP_
   4029     vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
   4030     vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
   4031     vqzip.init();
   4032     vqzip_sei_info.enabled = true;
   4033 #endif
   4034 
   4035     return true;
   4036 }
   4037 
   4038 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
   4039 {
   4040     // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
   4041     if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
   4042         return false;
   4043 
   4044     // Check for bframes with Hier-P-Hybrid
   4045     if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
   4046         return false;
   4047 
   4048     // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
   4049     if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
   4050            hier_layers.hier_mode == HIER_B || ltrinfo.count))
   4051         return false;
   4052 
   4053     // Check for LTR with Hier-P-Hybrid
   4054     if (count && hier_layers.hier_mode == HIER_P_HYBRID)
   4055         return false;
   4056 
   4057     return true;
   4058 }
   4059 
   4060 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
   4061                                     OMX_U32 num_layers)
   4062 {
   4063     struct v4l2_control control;
   4064 
   4065     if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
   4066         DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
   4067         return false;
   4068     }
   4069 
   4070     if (type == QOMX_HIERARCHICALCODING_P) {
   4071         // Reduce layer count by 1 before sending to driver. This avoids
   4072         // driver doing the same in multiple places.
   4073         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
   4074         control.value = num_layers - 1;
   4075         DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers);
   4076         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   4077             DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed");
   4078             return false;
   4079         }
   4080         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
   4081         control.value = num_layers - 1;
   4082         DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
   4083         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   4084             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
   4085             return false;
   4086         }
   4087         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4088             DEBUG_PRINT_LOW("Set H264_SVC_NAL");
   4089             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
   4090             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
   4091             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   4092                 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
   4093                 return false;
   4094             }
   4095         }
   4096         hier_layers.hier_mode = HIER_P;
   4097     } else if (type == QOMX_HIERARCHICALCODING_B) {
   4098         if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
   4099             DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
   4100             return false;
   4101         }
   4102         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
   4103         control.value = num_layers - 1;
   4104         DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
   4105         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   4106             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
   4107             return false;
   4108         }
   4109         hier_layers.hier_mode = HIER_B;
   4110     } else {
   4111         DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
   4112         return false;
   4113     }
   4114     hier_layers.numlayers = num_layers;
   4115     return true;
   4116 }
   4117 
   4118 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
   4119 {
   4120     struct v4l2_control control;
   4121 
   4122     DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
   4123 
   4124     if (enable == OMX_FALSE) {
   4125         /* No easy way to turn off extradata to the driver
   4126          * at the moment */
   4127         return false;
   4128     }
   4129 
   4130     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   4131     switch (extra_data) {
   4132         case OMX_ExtraDataVideoEncoderSliceInfo:
   4133             control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
   4134             break;
   4135         case OMX_ExtraDataVideoEncoderMBInfo:
   4136             control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
   4137             break;
   4138         case OMX_ExtraDataFrameDimension:
   4139             control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
   4140             break;
   4141         default:
   4142             DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
   4143             return false;
   4144     }
   4145 
   4146     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   4147         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
   4148                 (unsigned int)extra_data, errno);
   4149         return false;
   4150     }
   4151 
   4152     return true;
   4153 }
   4154 
   4155 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
   4156 {
   4157     struct v4l2_control control;
   4158 
   4159     if (enable) {
   4160         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
   4161         control.value = 1;
   4162         DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
   4163 
   4164         if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4165             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   4166                 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
   4167                 return false;
   4168             } else {
   4169                 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
   4170                 slice_mode.enable = 1;
   4171             }
   4172         } else {
   4173             DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
   4174                     "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
   4175                     m_sVenc_cfg.codectype);
   4176         }
   4177     } else {
   4178         DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
   4179     }
   4180 
   4181     return true;
   4182 }
   4183 
   4184 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
   4185 {
   4186     int rc;
   4187     struct v4l2_control control;
   4188     struct v4l2_ext_control ctrl[4];
   4189     struct v4l2_ext_controls controls;
   4190 
   4191     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
   4192     ctrl[0].value = initqp->nQpI;
   4193     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
   4194     ctrl[1].value = initqp->nQpP;
   4195     ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
   4196     ctrl[2].value = initqp->nQpB;
   4197     ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
   4198     ctrl[3].value = initqp->bEnableInitQp;
   4199 
   4200     controls.count = 4;
   4201     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   4202     controls.controls = ctrl;
   4203 
   4204     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
   4205                     controls.controls[0].id, controls.controls[0].value,
   4206                     controls.controls[1].id, controls.controls[1].value,
   4207                     controls.controls[2].id, controls.controls[2].value,
   4208                     controls.controls[3].id, controls.controls[3].value);
   4209 
   4210     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   4211     if (rc) {
   4212         DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
   4213         return false;
   4214     }
   4215 
   4216     init_qp.iframeqp = initqp->nQpI;
   4217     init_qp.pframeqp = initqp->nQpP;
   4218     init_qp.bframeqp = initqp->nQpB;
   4219     init_qp.enableinitqp = initqp->bEnableInitQp;
   4220 
   4221     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
   4222                     controls.controls[0].id, controls.controls[0].value,
   4223                     controls.controls[1].id, controls.controls[1].value,
   4224                     controls.controls[2].id, controls.controls[2].value,
   4225                     controls.controls[3].id, controls.controls[3].value);
   4226     return true;
   4227 }
   4228 
   4229 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
   4230     OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
   4231 {
   4232     int rc;
   4233     struct v4l2_control control;
   4234 
   4235     DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
   4236         primaries, range, transfer_chars, matrix_coeffs);
   4237 
   4238     control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
   4239     control.value = primaries;
   4240 
   4241     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4242     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4243 
   4244     if (rc) {
   4245         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
   4246         return false;
   4247     }
   4248 
   4249     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4250 
   4251     color_space.primaries = control.value;
   4252 
   4253     control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
   4254     control.value = range;
   4255 
   4256     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4257     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4258 
   4259     if (rc) {
   4260         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
   4261         return false;
   4262     }
   4263 
   4264     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4265 
   4266     color_space.range = control.value;
   4267 
   4268     control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
   4269     control.value = transfer_chars;
   4270 
   4271     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4272     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4273 
   4274     if (rc) {
   4275         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
   4276         return false;
   4277     }
   4278 
   4279     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4280 
   4281     color_space.transfer_chars = control.value;
   4282 
   4283     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
   4284     control.value = matrix_coeffs;
   4285 
   4286     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4287     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4288 
   4289     if (rc) {
   4290         DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
   4291         return false;
   4292     }
   4293 
   4294     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4295 
   4296     color_space.matrix_coeffs = control.value;
   4297 
   4298     return true;
   4299 }
   4300 
   4301 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
   4302 {
   4303     int rc;
   4304     struct v4l2_control control;
   4305 
   4306     control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
   4307     control.value = i_frame_qp;
   4308 
   4309     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4310     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4311 
   4312     if (rc) {
   4313         DEBUG_PRINT_ERROR("Failed to set control");
   4314         return false;
   4315     }
   4316 
   4317     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4318     session_qp.iframeqp = control.value;
   4319 
   4320     control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
   4321     control.value = p_frame_qp;
   4322 
   4323     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4324     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4325 
   4326     if (rc) {
   4327         DEBUG_PRINT_ERROR("Failed to set control");
   4328         return false;
   4329     }
   4330 
   4331     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4332 
   4333     session_qp.pframeqp = control.value;
   4334 
   4335     if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
   4336             (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
   4337 
   4338         control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
   4339         control.value = b_frame_qp;
   4340 
   4341         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4342         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4343 
   4344         if (rc) {
   4345             DEBUG_PRINT_ERROR("Failed to set control");
   4346             return false;
   4347         }
   4348 
   4349         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4350 
   4351         session_qp.bframeqp = control.value;
   4352     }
   4353 
   4354     return true;
   4355 }
   4356 
   4357 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
   4358 {
   4359     int rc;
   4360     struct v4l2_control control;
   4361 
   4362     if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
   4363 
   4364         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
   4365             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
   4366         else
   4367             control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
   4368         control.value = min_qp;
   4369 
   4370         DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
   4371                 control.id, control.value);
   4372         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4373         if (rc) {
   4374             DEBUG_PRINT_ERROR("Failed to set control");
   4375             return false;
   4376         }
   4377 
   4378         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
   4379             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
   4380         else
   4381             control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
   4382         control.value = max_qp;
   4383 
   4384         DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
   4385                 control.id, control.value);
   4386         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4387         if (rc) {
   4388             DEBUG_PRINT_ERROR("Failed to set control");
   4389             return false;
   4390         }
   4391     } else {
   4392         DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
   4393             (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
   4394     }
   4395 
   4396     return true;
   4397 }
   4398 
   4399 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
   4400 {
   4401     struct venc_profile requested_profile = {0};
   4402     struct ven_profilelevel requested_level = {0};
   4403     unsigned long mb_per_frame = 0;
   4404     DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
   4405             (unsigned int)eProfile, (unsigned int)eLevel);
   4406     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
   4407         ((m_sVenc_cfg.dvs_width + 15) >> 4);
   4408 
   4409     if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
   4410         DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
   4411         return true;
   4412     }
   4413 
   4414     if (vqzip_sei_info.enabled) {
   4415         DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
   4416         return true;
   4417     }
   4418 
   4419     DEBUG_PRINT_LOW("Validating Profile/Level from table");
   4420 
   4421     if (!venc_validate_profile_level(&eProfile, &eLevel)) {
   4422         DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
   4423         return false;
   4424     }
   4425 
   4426     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   4427         DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
   4428                 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
   4429                 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
   4430 
   4431         if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
   4432             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
   4433         } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
   4434             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
   4435         } else {
   4436             DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
   4437                     (unsigned int)eProfile);
   4438             return false;
   4439         }
   4440 
   4441         DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
   4442                 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
   4443                 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
   4444                 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
   4445 
   4446         if (mb_per_frame >= 3600) {
   4447             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
   4448                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   4449 
   4450             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
   4451                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   4452         } else {
   4453             switch (eLevel) {
   4454                 case OMX_VIDEO_MPEG4Level0:
   4455                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
   4456                     break;
   4457                 case OMX_VIDEO_MPEG4Level0b:
   4458                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
   4459                     break;
   4460                 case OMX_VIDEO_MPEG4Level1:
   4461                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
   4462                     break;
   4463                 case OMX_VIDEO_MPEG4Level2:
   4464                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
   4465                     break;
   4466                 case OMX_VIDEO_MPEG4Level3:
   4467                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
   4468                     break;
   4469                 case OMX_VIDEO_MPEG4Level4a:
   4470                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
   4471                     break;
   4472                 case OMX_VIDEO_MPEG4Level5:
   4473                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   4474                     break;
   4475                 default:
   4476                     return false;
   4477                     // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
   4478                     break;
   4479             }
   4480         }
   4481     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   4482 
   4483         switch (eProfile) {
   4484             case OMX_VIDEO_H263ProfileBaseline:
   4485                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
   4486                 break;
   4487             case OMX_VIDEO_H263ProfileH320Coding:
   4488                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
   4489                 break;
   4490             case OMX_VIDEO_H263ProfileBackwardCompatible:
   4491                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
   4492                 break;
   4493             case OMX_VIDEO_H263ProfileISWV2:
   4494                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
   4495                 break;
   4496             case OMX_VIDEO_H263ProfileISWV3:
   4497                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
   4498                 break;
   4499             case OMX_VIDEO_H263ProfileHighCompression:
   4500                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
   4501                 break;
   4502             case OMX_VIDEO_H263ProfileInternet:
   4503                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
   4504                 break;
   4505             case OMX_VIDEO_H263ProfileInterlace:
   4506                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
   4507                 break;
   4508             case OMX_VIDEO_H263ProfileHighLatency:
   4509                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
   4510                 break;
   4511             default:
   4512                 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
   4513                         requested_profile.profile);
   4514                 return false;
   4515         }
   4516 
   4517         //profile level
   4518         switch (eLevel) {
   4519             case OMX_VIDEO_H263Level10:
   4520                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
   4521                 break;
   4522             case OMX_VIDEO_H263Level20:
   4523                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
   4524                 break;
   4525             case OMX_VIDEO_H263Level30:
   4526                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
   4527                 break;
   4528             case OMX_VIDEO_H263Level40:
   4529                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
   4530                 break;
   4531             case OMX_VIDEO_H263Level45:
   4532                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
   4533                 break;
   4534             case OMX_VIDEO_H263Level50:
   4535                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
   4536                 break;
   4537             case OMX_VIDEO_H263Level60:
   4538                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
   4539                 break;
   4540             case OMX_VIDEO_H263Level70:
   4541                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
   4542                 break;
   4543             default:
   4544                 return false;
   4545                 break;
   4546         }
   4547     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4548         if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
   4549             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
   4550         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline ||
   4551                   eProfile == OMX_VIDEO_AVCProfileConstrainedBaseline) {
   4552             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
   4553         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh ||
   4554                   eProfile == OMX_VIDEO_AVCProfileConstrainedHigh) {
   4555             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
   4556         } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
   4557             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
   4558         } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
   4559             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
   4560         } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
   4561             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
   4562         } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
   4563             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
   4564         } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
   4565             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
   4566         } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
   4567             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
   4568         } else {
   4569             DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
   4570                     requested_profile.profile);
   4571             return false;
   4572         }
   4573 
   4574         //profile level
   4575         switch (eLevel) {
   4576             case OMX_VIDEO_AVCLevel1:
   4577                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
   4578                 break;
   4579             case OMX_VIDEO_AVCLevel1b:
   4580                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
   4581                 break;
   4582             case OMX_VIDEO_AVCLevel11:
   4583                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
   4584                 break;
   4585             case OMX_VIDEO_AVCLevel12:
   4586                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
   4587                 break;
   4588             case OMX_VIDEO_AVCLevel13:
   4589                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
   4590                 break;
   4591             case OMX_VIDEO_AVCLevel2:
   4592                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
   4593                 break;
   4594             case OMX_VIDEO_AVCLevel21:
   4595                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
   4596                 break;
   4597             case OMX_VIDEO_AVCLevel22:
   4598                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
   4599                 break;
   4600             case OMX_VIDEO_AVCLevel3:
   4601                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
   4602                 break;
   4603             case OMX_VIDEO_AVCLevel31:
   4604                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
   4605                 break;
   4606             case OMX_VIDEO_AVCLevel32:
   4607                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
   4608                 break;
   4609             case OMX_VIDEO_AVCLevel4:
   4610                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
   4611                 break;
   4612             case OMX_VIDEO_AVCLevel41:
   4613                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
   4614                 break;
   4615             case OMX_VIDEO_AVCLevel42:
   4616                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
   4617                 break;
   4618             case OMX_VIDEO_AVCLevel5:
   4619                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
   4620                 break;
   4621             case OMX_VIDEO_AVCLevel51:
   4622                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
   4623                 break;
   4624             case OMX_VIDEO_AVCLevel52:
   4625                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
   4626                 break;
   4627             case OMX_VIDEO_AVCLevelMax:
   4628                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
   4629                 break;
   4630             default :
   4631                 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
   4632                         requested_level.level);
   4633                 return false;
   4634                 break;
   4635         }
   4636     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   4637         if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
   4638             DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
   4639                         (unsigned int)eProfile);
   4640             return false;
   4641         }
   4642         requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
   4643         m_profile_set = true;
   4644         switch(eLevel) {
   4645             case OMX_VIDEO_VP8Level_Version0:
   4646                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
   4647                 break;
   4648             case OMX_VIDEO_VP8Level_Version1:
   4649                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
   4650                 break;
   4651             default:
   4652                 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
   4653                             (unsigned int)eLevel);
   4654                 return false;
   4655                 break;
   4656         }
   4657     }  else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   4658         if (eProfile == OMX_VIDEO_HEVCProfileMain) {
   4659             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
   4660         } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
   4661             requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
   4662         } else {
   4663             DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
   4664                     requested_profile.profile);
   4665             return false;
   4666         }
   4667 
   4668         //profile level
   4669         switch (eLevel) {
   4670             case OMX_VIDEO_HEVCMainTierLevel1:
   4671                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
   4672                 break;
   4673             case OMX_VIDEO_HEVCHighTierLevel1:
   4674                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
   4675                 break;
   4676             case OMX_VIDEO_HEVCMainTierLevel2:
   4677                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
   4678                 break;
   4679             case OMX_VIDEO_HEVCHighTierLevel2:
   4680                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
   4681                 break;
   4682             case OMX_VIDEO_HEVCMainTierLevel21:
   4683                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
   4684                 break;
   4685             case OMX_VIDEO_HEVCHighTierLevel21:
   4686                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
   4687                 break;
   4688             case OMX_VIDEO_HEVCMainTierLevel3:
   4689                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
   4690                 break;
   4691             case OMX_VIDEO_HEVCHighTierLevel3:
   4692                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
   4693                 break;
   4694             case OMX_VIDEO_HEVCMainTierLevel31:
   4695                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
   4696                 break;
   4697             case OMX_VIDEO_HEVCHighTierLevel31:
   4698                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
   4699                 break;
   4700             case OMX_VIDEO_HEVCMainTierLevel4:
   4701                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
   4702                 break;
   4703             case OMX_VIDEO_HEVCHighTierLevel4:
   4704                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
   4705                 break;
   4706             case OMX_VIDEO_HEVCMainTierLevel41:
   4707                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
   4708                 break;
   4709             case OMX_VIDEO_HEVCHighTierLevel41:
   4710                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
   4711                 break;
   4712             case OMX_VIDEO_HEVCMainTierLevel5:
   4713                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
   4714                 break;
   4715             case OMX_VIDEO_HEVCHighTierLevel5:
   4716                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
   4717                 break;
   4718             case OMX_VIDEO_HEVCMainTierLevel51:
   4719                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
   4720                 break;
   4721             case OMX_VIDEO_HEVCHighTierLevel51:
   4722                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
   4723                 break;
   4724             case OMX_VIDEO_HEVCMainTierLevel52:
   4725                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
   4726                 break;
   4727             case OMX_VIDEO_HEVCHighTierLevel52:
   4728                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
   4729                 break;
   4730             case OMX_VIDEO_HEVCMainTierLevel6:
   4731                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
   4732                 break;
   4733             case OMX_VIDEO_HEVCHighTierLevel6:
   4734                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
   4735                 break;
   4736             case OMX_VIDEO_HEVCMainTierLevel61:
   4737                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
   4738                 break;
   4739             case OMX_VIDEO_HEVCHighTierLevel61:
   4740                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
   4741                 break;
   4742             default :
   4743                 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
   4744                         requested_level.level);
   4745                 return false;
   4746         }
   4747     }
   4748 
   4749     if (!m_profile_set) {
   4750         int rc;
   4751         struct v4l2_control control;
   4752 
   4753         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4754             control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
   4755         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   4756             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
   4757         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   4758             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
   4759         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   4760             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
   4761         } else {
   4762             DEBUG_PRINT_ERROR("Wrong CODEC");
   4763             return false;
   4764         }
   4765 
   4766         control.value = requested_profile.profile;
   4767 
   4768         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4769         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4770 
   4771         if (rc) {
   4772             DEBUG_PRINT_ERROR("Failed to set control");
   4773             return false;
   4774         }
   4775 
   4776         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4777 
   4778         codec_profile.profile = control.value;
   4779         m_profile_set = true;
   4780     }
   4781 
   4782     if (!m_level_set) {
   4783         int rc;
   4784         struct v4l2_control control;
   4785 
   4786         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4787             control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
   4788         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   4789             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
   4790         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   4791             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
   4792         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   4793             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
   4794         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   4795             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
   4796         } else {
   4797             DEBUG_PRINT_ERROR("Wrong CODEC");
   4798             return false;
   4799         }
   4800 
   4801         control.value = requested_level.level;
   4802 
   4803         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4804         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4805 
   4806         if (rc) {
   4807             DEBUG_PRINT_ERROR("Failed to set control");
   4808             return false;
   4809         }
   4810 
   4811         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4812 
   4813         profile_level.level = control.value;
   4814         m_level_set = true;
   4815     }
   4816 
   4817     return true;
   4818 }
   4819 
   4820 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
   4821 {
   4822 
   4823     struct venc_voptimingcfg vop_timing_cfg;
   4824 
   4825     DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
   4826             (unsigned int)TimeIncRes);
   4827 
   4828     vop_timing_cfg.voptime_resolution = TimeIncRes;
   4829 
   4830     voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
   4831     return true;
   4832 }
   4833 
   4834 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) {
   4835 #if _ANDROID_
   4836     // Android defines nBFrames as number of Bs between I OR P
   4837     // Per the spec, nBFrames is number of Bs between I
   4838     OMX_U32 nBs = nBFrames * (nPFrames + 1);
   4839     DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs);
   4840     nBFrames = nBs;
   4841 #endif //_ANDROID_
   4842    return venc_set_intra_period(nPFrames, nBFrames);
   4843 }
   4844 
   4845 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
   4846 {
   4847 
   4848     DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
   4849     int rc;
   4850     struct v4l2_control control;
   4851     int pframe = 0, bframe = 0;
   4852 
   4853     if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
   4854             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
   4855             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
   4856             (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
   4857             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
   4858         nBFrames=0;
   4859     }
   4860 
   4861     if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
   4862         DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
   4863         return false;
   4864     }
   4865 
   4866     intra_period.num_pframes = nPFrames;
   4867     intra_period.num_bframes = nBFrames;
   4868 
   4869     if (!venc_calibrate_gop() && !is_thulium_v1)
   4870     {
   4871         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
   4872         return false;
   4873     }
   4874 
   4875     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
   4876     control.value = intra_period.num_pframes;
   4877     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4878 
   4879     if (rc) {
   4880         DEBUG_PRINT_ERROR("Failed to set control");
   4881         return false;
   4882     }
   4883 
   4884     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4885 
   4886     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
   4887     control.value = intra_period.num_bframes;
   4888     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4889     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4890 
   4891     if (rc) {
   4892         DEBUG_PRINT_ERROR("Failed to set control");
   4893         return false;
   4894     }
   4895 
   4896     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
   4897 
   4898     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
   4899         m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   4900         control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
   4901         control.value = 1;
   4902 
   4903         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4904 
   4905         if (rc) {
   4906             DEBUG_PRINT_ERROR("Failed to set control");
   4907             return false;
   4908         }
   4909         idrperiod.idrperiod = 1;
   4910     }
   4911     return true;
   4912 }
   4913 
   4914 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
   4915 {
   4916     int rc = 0;
   4917     struct v4l2_control control;
   4918     DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
   4919             (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
   4920 
   4921     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
   4922         DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
   4923         return false;
   4924     }
   4925 
   4926     if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
   4927         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   4928         return false;
   4929     }
   4930 
   4931     if (!intra_period.num_bframes)
   4932         intra_period.num_pframes = nPFrames;
   4933     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
   4934     control.value = nIDRPeriod;
   4935 
   4936     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4937 
   4938     if (rc) {
   4939         DEBUG_PRINT_ERROR("Failed to set control");
   4940         return false;
   4941     }
   4942 
   4943     idrperiod.idrperiod = nIDRPeriod;
   4944     return true;
   4945 }
   4946 
   4947 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
   4948 {
   4949     int rc = 0;
   4950     struct v4l2_control control;
   4951 
   4952     DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
   4953 
   4954     if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
   4955             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
   4956 
   4957         control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
   4958         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   4959 
   4960         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4961         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4962 
   4963         if (rc) {
   4964             DEBUG_PRINT_ERROR("Failed to set control");
   4965             return false;
   4966         }
   4967 
   4968         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4969         entropy.longentropysel = control.value;
   4970 
   4971         if (i_cabac_level == 0) {
   4972             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
   4973         } else if (i_cabac_level == 1) {
   4974             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
   4975         } else if (i_cabac_level == 2) {
   4976             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
   4977         }
   4978 
   4979         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
   4980         //control.value = entropy_cfg.cabacmodel;
   4981         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4982         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4983 
   4984         if (rc) {
   4985             DEBUG_PRINT_ERROR("Failed to set control");
   4986             return false;
   4987         }
   4988 
   4989         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4990         entropy.cabacmodel=control.value;
   4991     } else if (!enable) {
   4992         control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
   4993         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   4994         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   4995         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   4996 
   4997         if (rc) {
   4998             DEBUG_PRINT_ERROR("Failed to set control");
   4999             return false;
   5000         }
   5001 
   5002         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5003         entropy.longentropysel=control.value;
   5004     } else {
   5005         DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
   5006         return false;
   5007     }
   5008 
   5009     return true;
   5010 }
   5011 
   5012 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
   5013 {
   5014     int rc;
   5015     struct v4l2_control control;
   5016     bool status = true;
   5017 
   5018     if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
   5019         control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
   5020     } else {
   5021         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
   5022     }
   5023 
   5024     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   5025     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   5026     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5027 
   5028     if (rc) {
   5029         DEBUG_PRINT_ERROR("Failed to set control");
   5030         return false;
   5031     }
   5032 
   5033     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5034     multislice.mslice_mode=control.value;
   5035 
   5036     if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
   5037 
   5038         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
   5039         control.value = nSlicesize;
   5040         DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
   5041         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5042 
   5043         if (rc) {
   5044             DEBUG_PRINT_ERROR("Failed to set control");
   5045             return false;
   5046         }
   5047 
   5048         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5049         multislice.mslice_size=control.value;
   5050 
   5051     }
   5052 
   5053     return status;
   5054 }
   5055 
   5056 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
   5057 {
   5058     bool status = true;
   5059     int rc;
   5060     struct v4l2_control control_mode,control_mbs;
   5061     control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
   5062 
   5063     // There is no disabled mode.  Disabled mode is indicated by a 0 count.
   5064     if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
   5065         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
   5066         return status;
   5067     } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
   5068             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   5069         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
   5070         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
   5071         control_mbs.value=irMBs;
   5072     } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
   5073             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   5074         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
   5075         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
   5076         control_mbs.value=irMBs;
   5077     } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
   5078             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   5079         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
   5080     } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
   5081             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   5082         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
   5083         control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
   5084         control_mbs.value = irMBs;
   5085     } else {
   5086         DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
   5087                 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
   5088         return false;
   5089     }
   5090 
   5091     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
   5092     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
   5093 
   5094     if (rc) {
   5095         DEBUG_PRINT_ERROR("Failed to set control");
   5096         return false;
   5097     }
   5098 
   5099     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
   5100 
   5101     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
   5102     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
   5103 
   5104     if (rc) {
   5105         DEBUG_PRINT_ERROR("Failed to set control");
   5106         return false;
   5107     }
   5108 
   5109     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
   5110 
   5111     intra_refresh.irmode = control_mode.value;
   5112     intra_refresh.mbcount = control_mbs.value;
   5113 
   5114     return status;
   5115 }
   5116 
   5117 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
   5118 {
   5119     bool status = true;
   5120     struct venc_headerextension hec_cfg;
   5121     struct venc_multiclicecfg multislice_cfg;
   5122     int rc;
   5123     OMX_U32 resynchMarkerSpacingBytes = 0;
   5124     struct v4l2_control control;
   5125 
   5126     memset(&control, 0, sizeof(control));
   5127 
   5128     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   5129         if (error_resilience->bEnableHEC) {
   5130             hec_cfg.header_extension = 1;
   5131         } else {
   5132             hec_cfg.header_extension = 0;
   5133         }
   5134 
   5135         hec.header_extension = error_resilience->bEnableHEC;
   5136     }
   5137 
   5138     if (error_resilience->bEnableRVLC) {
   5139         DEBUG_PRINT_ERROR("RVLC is not Supported");
   5140         return false;
   5141     }
   5142 
   5143     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
   5144             (error_resilience->bEnableDataPartitioning)) {
   5145         DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
   5146         return false;
   5147     }
   5148 
   5149     if (error_resilience->nResynchMarkerSpacing) {
   5150         resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
   5151         resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
   5152     }
   5153     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
   5154             (error_resilience->nResynchMarkerSpacing)) {
   5155         multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
   5156         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
   5157         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   5158         control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
   5159     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
   5160             error_resilience->bEnableDataPartitioning) {
   5161         multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
   5162         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
   5163         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   5164         control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
   5165     } else {
   5166         multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
   5167         multislice_cfg.mslice_size = 0;
   5168         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   5169         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
   5170     }
   5171 
   5172     DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
   5173             multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
   5174     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   5175     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5176 
   5177     if (rc) {
   5178        DEBUG_PRINT_ERROR("Failed to set Slice mode control");
   5179         return false;
   5180     }
   5181 
   5182     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   5183     multislice.mslice_mode=control.value;
   5184 
   5185     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
   5186     control.value = resynchMarkerSpacingBytes;
   5187     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   5188 
   5189     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5190 
   5191     if (rc) {
   5192        DEBUG_PRINT_ERROR("Failed to set MAX MB control");
   5193         return false;
   5194     }
   5195 
   5196     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   5197     multislice.mslice_mode = multislice_cfg.mslice_mode;
   5198     multislice.mslice_size = multislice_cfg.mslice_size;
   5199     return status;
   5200 }
   5201 
   5202 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
   5203 {
   5204     int rc;
   5205     struct v4l2_control control;
   5206     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
   5207 
   5208     if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
   5209         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
   5210     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
   5211         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
   5212     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
   5213         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
   5214     }
   5215 
   5216     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   5217     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5218 
   5219     if (rc) {
   5220         return false;
   5221     }
   5222 
   5223     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5224 
   5225     dbkfilter.db_mode=control.value;
   5226 
   5227     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
   5228     control.value=0;
   5229 
   5230     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   5231     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5232 
   5233     if (rc) {
   5234         return false;
   5235     }
   5236 
   5237     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5238     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
   5239     control.value=0;
   5240     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   5241     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5242 
   5243     if (rc) {
   5244         return false;
   5245     }
   5246 
   5247     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5248 
   5249 
   5250     dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
   5251     return true;
   5252 }
   5253 
   5254 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
   5255 {
   5256     DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
   5257             (unsigned int)nTargetBitrate);
   5258     struct v4l2_control control;
   5259     int rc = 0;
   5260     control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
   5261     control.value = nTargetBitrate;
   5262 
   5263     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   5264     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5265 
   5266     if (rc) {
   5267         DEBUG_PRINT_ERROR("Failed to set control");
   5268         return false;
   5269     }
   5270 
   5271     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5272 
   5273 
   5274     m_sVenc_cfg.targetbitrate = control.value;
   5275     bitrate.target_bitrate = control.value;
   5276 
   5277     if (!config) {
   5278         m_level_set = false;
   5279 
   5280         if (venc_set_profile_level(0, 0)) {
   5281             DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
   5282         }
   5283     }
   5284 
   5285     // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
   5286     //  has been specified
   5287     if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
   5288         OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
   5289                 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
   5290 
   5291         DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
   5292         for (OMX_U32 i = 0; i < numLayers; ++i) {
   5293             layerBitrates[i] =
   5294                     (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
   5295             DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
   5296                     i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
   5297                     layerBitrates[i], bitrate.target_bitrate);
   5298         }
   5299         if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
   5300             return false;
   5301         }
   5302     }
   5303 
   5304     return true;
   5305 }
   5306 
   5307 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
   5308 {
   5309     struct v4l2_streamparm parm;
   5310     int rc = 0;
   5311     struct venc_framerate frame_rate_cfg;
   5312     Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
   5313     parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5314     parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
   5315     parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
   5316 
   5317     if (frame_rate_cfg.fps_numerator > 0)
   5318         rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
   5319 
   5320     if (rc) {
   5321         DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
   5322         return false;
   5323     }
   5324 
   5325     m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
   5326     m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
   5327 
   5328     if (!config) {
   5329         m_level_set = false;
   5330 
   5331         if (venc_set_profile_level(0, 0)) {
   5332             DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
   5333         }
   5334     }
   5335 
   5336     return true;
   5337 }
   5338 
   5339 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
   5340 {
   5341     struct v4l2_format fmt;
   5342     int color_space = 0;
   5343     DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
   5344 
   5345     switch ((int)color_format) {
   5346         case OMX_COLOR_FormatYUV420SemiPlanar:
   5347         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
   5348             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
   5349             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
   5350             break;
   5351         case QOMX_COLOR_FormatYVU420SemiPlanar:
   5352             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
   5353             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
   5354             break;
   5355         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
   5356             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
   5357             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
   5358             break;
   5359         case QOMX_COLOR_Format32bitRGBA8888:
   5360             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
   5361             break;
   5362         case QOMX_COLOR_Format32bitRGBA8888Compressed:
   5363             m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
   5364             break;
   5365         default:
   5366             DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
   5367             m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
   5368             color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
   5369             DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
   5370             break;
   5371     }
   5372 
   5373     memset(&fmt, 0, sizeof(fmt));
   5374     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5375     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   5376     fmt.fmt.pix_mp.colorspace = color_space;
   5377     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   5378     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   5379 
   5380     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   5381         DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
   5382         return false;
   5383     }
   5384 
   5385     return true;
   5386 }
   5387 
   5388 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
   5389 {
   5390     DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
   5391 
   5392     if (intra_vop_refresh == OMX_TRUE) {
   5393         struct v4l2_control control;
   5394         int rc;
   5395         control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
   5396         control.value = 1;
   5397        DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   5398         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5399 
   5400         if (rc) {
   5401            DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
   5402             return false;
   5403         }
   5404 
   5405        DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   5406     } else {
   5407         DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
   5408     }
   5409 
   5410     return true;
   5411 }
   5412 
   5413 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
   5414 {
   5415     DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
   5416     struct v4l2_control control;
   5417     int rc;
   5418     control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
   5419     if (enable)
   5420         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
   5421     else
   5422         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
   5423 
   5424     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   5425     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5426     if (rc) {
   5427         DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
   5428         return false;
   5429     }
   5430     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   5431     deinterlace_enabled = true;
   5432     return true;
   5433 }
   5434 
   5435 bool venc_dev::venc_calibrate_gop()
   5436 {
   5437     int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
   5438     int num_sub_gops_in_a_gop;
   5439     nPframes = intra_period.num_pframes;
   5440     nBframes = intra_period.num_bframes;
   5441     nLayers = hier_layers.numlayers;
   5442     if (temporal_layers_config.nPLayers) {
   5443         nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
   5444     }
   5445 
   5446     if (!nPframes && nLayers) {
   5447         DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
   5448         return false;
   5449     }
   5450 
   5451     if (nLayers > 1) { /*Multi-layer encoding*/
   5452         sub_gop_size = 1 << (nLayers - 1);
   5453         /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
   5454          * below calculations we are ignoring +1 . Ignoring +1 in below
   5455          * calculations is not a mistake but intentional.
   5456          */
   5457         gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
   5458         num_sub_gops_in_a_gop = gop_size/sub_gop_size;
   5459         if (nBframes) { /*Hier-B case*/
   5460         /*
   5461             * Frame Type--> I  B  B  B  P  B  B  B  P  I  B  B  P ...
   5462             * Layer -->     0  2  1  2  0  2  1  2  0  0  2  1  2 ...
   5463             * nPframes = 2, nBframes = 6, nLayers = 3
   5464             *
   5465             * Intention is to keep the intraperiod as close as possible to what is desired
   5466             * by the client while adjusting nPframes and nBframes to meet other constraints.
   5467             * eg1: Input by client: nPframes =  9, nBframes = 14, nLayers = 2
   5468             *    Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
   5469             *
   5470             * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
   5471             *    Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
   5472             */
   5473             nPframes = num_sub_gops_in_a_gop;
   5474             nBframes = gop_size - nPframes;
   5475         } else { /*Hier-P case*/
   5476             /*
   5477             * Frame Type--> I  P  P  P  P  P  P  P  I  P  P  P  P ...
   5478             * Layer-->      0  2  1  2  0  2  1  2  0  2  1  2  0 ...
   5479             * nPframes =  7, nBframes = 0, nLayers = 3
   5480             *
   5481             * Intention is to keep the intraperiod as close as possible to what is desired
   5482             * by the client while adjusting nPframes and nBframes to meet other constraints.
   5483             * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
   5484             *    Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
   5485             *
   5486             * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
   5487             *     Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
   5488             */
   5489             nPframes = gop_size - 1;
   5490         }
   5491     } else { /*Single-layer encoding*/
   5492         if (nBframes) {
   5493             /* I  P  B  B  B  P  B  B  B   P   B   B   B   I   P   B   B...
   5494             *  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17...
   5495             * nPframes = 3, nBframes = 9, nLayers = 0
   5496             *
   5497             * ratio is rounded,
   5498             * eg1: nPframes = 9, nBframes = 11 => ratio = 1
   5499             * eg2: nPframes = 9, nBframes = 16 => ratio = 2
   5500             */
   5501             ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
   5502             nBframes = ratio * nPframes;
   5503         }
   5504     }
   5505     DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
   5506         intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
   5507     intra_period.num_pframes = nPframes;
   5508     intra_period.num_bframes = nBframes;
   5509     hier_layers.numlayers = nLayers;
   5510     return true;
   5511 }
   5512 
   5513 bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
   5514 {
   5515     struct v4l2_control control;
   5516     int rc = 0;
   5517     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
   5518     control.value = type;
   5519     DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
   5520     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5521     if (rc) {
   5522         DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
   5523             bitrate_type_string(type));
   5524         return false;
   5525     }
   5526     return true;
   5527 }
   5528 
   5529 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
   5530 {
   5531     DEBUG_PRINT_LOW("venc_set_layer_bitrates");
   5532     struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
   5533     struct v4l2_ext_controls controls;
   5534     int rc = 0;
   5535     OMX_U32 i;
   5536 
   5537     if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
   5538         DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
   5539         return false;
   5540     }
   5541 
   5542     for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
   5543         if (!layerBitrate[i]) {
   5544             DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
   5545             return false;
   5546         } else {
   5547             ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
   5548             ctrl[i].value = layerBitrate[i];
   5549         }
   5550     }
   5551     controls.count = numLayers;
   5552     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   5553     controls.controls = ctrl;
   5554 
   5555     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   5556     if (rc) {
   5557         DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
   5558         return false;
   5559     }
   5560 
   5561     DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
   5562     return true;
   5563 }
   5564 
   5565 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
   5566 {
   5567     DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
   5568     struct v4l2_control control;
   5569     int rc;
   5570 
   5571     if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
   5572         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
   5573         return false;
   5574     }
   5575 
   5576     if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
   5577         DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
   5578         return false;
   5579     }
   5580     if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
   5581        DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
   5582        return false;
   5583     }
   5584 
   5585     hier_layers.numlayers = hhp->nHpLayers;
   5586     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   5587         hier_layers.hier_mode = HIER_P_HYBRID;
   5588     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   5589         hier_layers.hier_mode = HIER_P;
   5590     }
   5591     if (venc_calibrate_gop()) {
   5592      // Update the driver with the new nPframes and nBframes
   5593         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
   5594         control.value = intra_period.num_pframes;
   5595         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5596         if (rc) {
   5597             DEBUG_PRINT_ERROR("Failed to set control");
   5598             return false;
   5599         }
   5600 
   5601         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
   5602         control.value = intra_period.num_bframes;
   5603         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5604         if (rc) {
   5605             DEBUG_PRINT_ERROR("Failed to set control");
   5606             return false;
   5607         }
   5608         DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
   5609                          intra_period.num_pframes, intra_period.num_bframes);
   5610     } else {
   5611         DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
   5612         return false;
   5613     }
   5614     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   5615         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
   5616     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   5617         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
   5618     }
   5619     control.value = hhp->nHpLayers - 1;
   5620 
   5621     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
   5622                     control.id, control.value);
   5623 
   5624     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5625     if (rc) {
   5626         DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
   5627         return false;
   5628     }
   5629 
   5630     DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
   5631                     control.id, control.value);
   5632     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   5633         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
   5634         control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
   5635         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   5636             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
   5637             return false;
   5638         }
   5639     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   5640         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
   5641         control.value = hhp->nHpLayers - 1;
   5642         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   5643             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
   5644             return false;
   5645         }
   5646     } else {
   5647         DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
   5648         return false;
   5649     }
   5650 
   5651     if(venc_set_session_qp_range (hhp->nMinQuantizer,
   5652                 hhp->nMaxQuantizer) == false) {
   5653         DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
   5654             (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
   5655         return false;
   5656     } else {
   5657         session_qp_values.minqp = hhp->nMinQuantizer;
   5658         session_qp_values.maxqp = hhp->nMaxQuantizer;
   5659     }
   5660 
   5661     OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
   5662     for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
   5663         layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
   5664         hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
   5665         DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
   5666     }
   5667     if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
   5668        DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
   5669             hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
   5670             hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
   5671             hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
   5672        return false;
   5673     }
   5674     hybrid_hp.nHpLayers = hhp->nHpLayers;
   5675 
   5676     // Set this or else the layer0 bitrate will be overwritten by
   5677     // default value in component
   5678     m_sVenc_cfg.targetbitrate  = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
   5679     hybrid_hp.nHpLayers = hhp->nHpLayers;
   5680     hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
   5681     hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
   5682     hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
   5683     return true;
   5684 }
   5685 
   5686 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
   5687 {
   5688     DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
   5689     struct v4l2_ext_control ctrl[2];
   5690     struct v4l2_ext_controls controls;
   5691     int rc;
   5692 
   5693     if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
   5694         DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
   5695         return false;
   5696     }
   5697 
   5698     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
   5699     if (enable)
   5700         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
   5701     else
   5702         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
   5703 
   5704     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
   5705     if (enable && count > 0)
   5706         ctrl[1].value = count;
   5707     else if (enable)
   5708         ctrl[1].value = 1;
   5709     else
   5710         ctrl[1].value = 0;
   5711 
   5712     controls.count = 2;
   5713     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   5714     controls.controls = ctrl;
   5715 
   5716     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
   5717                     controls.controls[0].id, controls.controls[0].value,
   5718                     controls.controls[1].id, controls.controls[1].value);
   5719 
   5720     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   5721     if (rc) {
   5722         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
   5723         return false;
   5724     }
   5725     ltrinfo.enabled = enable;
   5726     ltrinfo.count = count;
   5727 
   5728     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
   5729                     controls.controls[0].id, controls.controls[0].value,
   5730                     controls.controls[1].id, controls.controls[1].value);
   5731 
   5732     if (!venc_set_profile_level(0, 0)) {
   5733         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
   5734                 __func__);
   5735     } else {
   5736         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
   5737                 __func__, codec_profile.profile, profile_level.level);
   5738     }
   5739 
   5740     return true;
   5741 }
   5742 
   5743 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
   5744 {
   5745     DEBUG_PRINT_LOW("venc_use_goldenframe");
   5746     int rc = true;
   5747     struct v4l2_control control;
   5748 
   5749     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
   5750     control.value = frameIdx;
   5751 
   5752     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5753     if (rc) {
   5754         DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
   5755         return false;
   5756     }
   5757 
   5758     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
   5759                     control.id, control.value);
   5760     return true;
   5761 }
   5762 
   5763 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
   5764 {
   5765     DEBUG_PRINT_LOW("venc_set_goldenframe");
   5766     int rc = true;
   5767     struct v4l2_control control;
   5768 
   5769     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
   5770     control.value = frameIdx;
   5771 
   5772     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5773     if (rc) {
   5774         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
   5775         return false;
   5776     }
   5777 
   5778     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
   5779                     control.id, control.value);
   5780     return true;
   5781 }
   5782 
   5783 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
   5784 {
   5785     DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
   5786     struct v4l2_control control;
   5787     int rc;
   5788     struct v4l2_format fmt;
   5789     struct v4l2_requestbuffers bufreq;
   5790 
   5791     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
   5792     if (rotation_angle == 0)
   5793         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
   5794     else if (rotation_angle == 90)
   5795         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
   5796     else if (rotation_angle == 180)
   5797         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
   5798     else if (rotation_angle == 270)
   5799         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
   5800     else {
   5801         DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
   5802         return false;
   5803     }
   5804 
   5805     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   5806     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5807     if (rc) {
   5808         DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
   5809         return false;
   5810     }
   5811     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   5812 
   5813     memset(&fmt, 0, sizeof(fmt));
   5814     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5815     if (rotation_angle == 90 || rotation_angle == 270) {
   5816         OMX_U32 nWidth = m_sVenc_cfg.dvs_height;
   5817         OMX_U32 nHeight = m_sVenc_cfg.dvs_width;
   5818         m_sVenc_cfg.dvs_height = nHeight;
   5819         m_sVenc_cfg.dvs_width = nWidth;
   5820         DEBUG_PRINT_LOW("Rotation (%u) Flipping wxh to %lux%lu",
   5821                 rotation_angle, m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height);
   5822     }
   5823 
   5824     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   5825     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   5826     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   5827     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   5828         DEBUG_PRINT_ERROR("Failed to set format on capture port");
   5829         return false;
   5830     }
   5831 
   5832     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   5833     bufreq.memory = V4L2_MEMORY_USERPTR;
   5834     bufreq.count = m_sOutput_buff_property.actualcount;
   5835     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5836     if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   5837         DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
   5838             return false;
   5839     }
   5840     if (bufreq.count >= m_sOutput_buff_property.mincount)
   5841         m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
   5842 
   5843     return true;
   5844 }
   5845 
   5846 bool venc_dev::venc_set_searchrange()
   5847 {
   5848     DEBUG_PRINT_LOW("venc_set_searchrange");
   5849     struct v4l2_control control;
   5850     struct v4l2_ext_control ctrl[6];
   5851     struct v4l2_ext_controls controls;
   5852     int rc;
   5853 
   5854     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   5855         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
   5856         ctrl[0].value = 16;
   5857         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
   5858         ctrl[1].value = 4;
   5859         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
   5860         ctrl[2].value = 16;
   5861         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
   5862         ctrl[3].value = 4;
   5863         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
   5864         ctrl[4].value = 12;
   5865         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
   5866         ctrl[5].value = 4;
   5867     } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
   5868                (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
   5869         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
   5870         ctrl[0].value = 16;
   5871         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
   5872         ctrl[1].value = 4;
   5873         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
   5874         ctrl[2].value = 16;
   5875         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
   5876         ctrl[3].value = 4;
   5877         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
   5878         ctrl[4].value = 12;
   5879         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
   5880         ctrl[5].value = 4;
   5881     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   5882         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
   5883         ctrl[0].value = 4;
   5884         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
   5885         ctrl[1].value = 4;
   5886         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
   5887         ctrl[2].value = 4;
   5888         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
   5889         ctrl[3].value = 4;
   5890         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
   5891         ctrl[4].value = 4;
   5892         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
   5893         ctrl[5].value = 4;
   5894     } else {
   5895         DEBUG_PRINT_ERROR("Invalid codec type");
   5896         return false;
   5897     }
   5898     controls.count = 6;
   5899     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   5900     controls.controls = ctrl;
   5901 
   5902     DEBUG_PRINT_LOW(" Calling IOCTL set control for"
   5903         "id=%x, val=%d id=%x, val=%d"
   5904         "id=%x, val=%d id=%x, val=%d"
   5905         "id=%x, val=%d id=%x, val=%d",
   5906         controls.controls[0].id, controls.controls[0].value,
   5907         controls.controls[1].id, controls.controls[1].value,
   5908         controls.controls[2].id, controls.controls[2].value,
   5909         controls.controls[3].id, controls.controls[3].value,
   5910         controls.controls[4].id, controls.controls[4].value,
   5911         controls.controls[5].id, controls.controls[5].value);
   5912 
   5913     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   5914     if (rc) {
   5915         DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
   5916         return false;
   5917     }
   5918     return true;
   5919 }
   5920 
   5921 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
   5922 {
   5923     bool status = true;
   5924     struct v4l2_control control;
   5925     int rc = 0;
   5926     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
   5927 
   5928     switch (eControlRate) {
   5929         case OMX_Video_ControlRateDisable:
   5930             control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
   5931             break;
   5932         case OMX_Video_ControlRateVariableSkipFrames:
   5933             (supported_rc_modes & RC_VBR_VFR) ?
   5934                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
   5935                 status = false;
   5936             break;
   5937         case OMX_Video_ControlRateVariable:
   5938             (supported_rc_modes & RC_VBR_CFR) ?
   5939                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
   5940                 status = false;
   5941             break;
   5942         case OMX_Video_ControlRateConstantSkipFrames:
   5943             (supported_rc_modes & RC_CBR_VFR) ?
   5944                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
   5945                 status = false;
   5946             break;
   5947         case OMX_Video_ControlRateConstant:
   5948             (supported_rc_modes & RC_CBR_CFR) ?
   5949                 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
   5950                 status = false;
   5951             break;
   5952         default:
   5953             status = false;
   5954             break;
   5955     }
   5956 
   5957     if (status) {
   5958 
   5959         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   5960         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   5961 
   5962         if (rc) {
   5963             DEBUG_PRINT_ERROR("Failed to set control");
   5964             return false;
   5965         }
   5966 
   5967         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   5968 
   5969         rate_ctrl.rcmode = control.value;
   5970     }
   5971 
   5972 #ifdef _VQZIP_
   5973     if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
   5974         && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   5975         /* Enable VQZIP SEI by default for camcorder RC modes */
   5976 
   5977         control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
   5978         control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
   5979         DEBUG_PRINT_HIGH("Set VQZIP SEI:");
   5980         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
   5981             DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
   5982         }
   5983     }
   5984 #endif //_VQZIP_
   5985 
   5986     return status;
   5987 }
   5988 
   5989 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
   5990 {
   5991     bool status = true;
   5992     struct v4l2_control control;
   5993     int rc = 0;
   5994     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   5995 
   5996     switch (ePerfLevel) {
   5997     case OMX_QCOM_PerfLevelNominal:
   5998         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   5999         break;
   6000     case OMX_QCOM_PerfLevelTurbo:
   6001         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   6002         break;
   6003     default:
   6004         status = false;
   6005         break;
   6006     }
   6007 
   6008     if (status) {
   6009         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   6010         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   6011 
   6012         if (rc) {
   6013             DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
   6014             return false;
   6015         }
   6016 
   6017         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   6018     }
   6019     return status;
   6020 }
   6021 
   6022 bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
   6023 {
   6024     struct v4l2_control control;
   6025     if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
   6026         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
   6027         control.value = mode;
   6028         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
   6029         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6030             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
   6031             return false;
   6032         }
   6033         return true;
   6034     } else {
   6035         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
   6036         return false;
   6037     }
   6038 }
   6039 
   6040 bool venc_dev::venc_set_qp(OMX_U32 nQp)
   6041 {
   6042     struct v4l2_control control;
   6043     if (nQp) {
   6044         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
   6045         control.value = nQp;
   6046         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
   6047         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6048             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
   6049             return false;
   6050         }
   6051     } else {
   6052         DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
   6053         return false;
   6054     }
   6055     return true;
   6056 }
   6057 
   6058 bool venc_dev::venc_set_aspectratio(void *nSar)
   6059 {
   6060     int rc;
   6061     struct v4l2_control control;
   6062     struct v4l2_ext_control ctrl[2];
   6063     struct v4l2_ext_controls controls;
   6064     QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
   6065 
   6066     sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
   6067 
   6068     ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
   6069     ctrl[0].value = sar->nSARWidth;
   6070     ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
   6071     ctrl[1].value = sar->nSARHeight;
   6072 
   6073     controls.count = 2;
   6074     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   6075     controls.controls = ctrl;
   6076 
   6077     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
   6078                     controls.controls[0].id, controls.controls[0].value,
   6079                     controls.controls[1].id, controls.controls[1].value);
   6080 
   6081     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   6082     if (rc) {
   6083         DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
   6084         return false;
   6085     }
   6086 
   6087     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
   6088                     controls.controls[0].id, controls.controls[0].value,
   6089                     controls.controls[1].id, controls.controls[1].value);
   6090     return true;
   6091 }
   6092 
   6093 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
   6094 {
   6095     struct v4l2_control control;
   6096     if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
   6097             (hierp_layers <= hier_layers.numlayers)) {
   6098         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
   6099         control.value = hierp_layers - 1;
   6100         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
   6101         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6102             DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
   6103             return false;
   6104         }
   6105         return true;
   6106     } else {
   6107         DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
   6108                 hierp_layers);
   6109         return false;
   6110     }
   6111 }
   6112 
   6113 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
   6114 {
   6115     struct v4l2_control control;
   6116     if (hier_layers.hier_mode == HIER_P) {
   6117         control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
   6118         control.value = baseid;
   6119         DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
   6120         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6121             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
   6122             return false;
   6123         }
   6124         return true;
   6125     } else {
   6126         DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
   6127                 hier_layers.hier_mode);
   6128         return false;
   6129     }
   6130 }
   6131 
   6132 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
   6133 {
   6134     struct v4l2_control control;
   6135     int rc = 0;
   6136     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
   6137 
   6138     if (enable)
   6139         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
   6140     else
   6141         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
   6142 
   6143     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   6144     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   6145     if (rc) {
   6146         DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
   6147         return false;
   6148     }
   6149     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   6150     return true;
   6151 }
   6152 
   6153 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
   6154 {
   6155     struct v4l2_control control;
   6156     int rc = 0;
   6157     control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
   6158     control.value = nPeakBitrate;
   6159 
   6160     DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
   6161 
   6162     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   6163     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   6164 
   6165     if (rc) {
   6166         DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
   6167         return false;
   6168     }
   6169 
   6170     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   6171 
   6172     return true;
   6173 }
   6174 
   6175 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
   6176 {
   6177     struct v4l2_control control;
   6178     int rc = 0;
   6179     control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
   6180 
   6181     if (enable)
   6182         control.value = 1;
   6183     else
   6184         control.value = 0;
   6185 
   6186     DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
   6187 
   6188     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   6189 
   6190     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   6191     if (rc) {
   6192         DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
   6193         return false;
   6194     }
   6195     vpx_err_resilience.enable = 1;
   6196     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   6197     return true;
   6198 }
   6199 
   6200 bool venc_dev::venc_set_priority(OMX_U32 priority) {
   6201     struct v4l2_control control;
   6202 
   6203     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
   6204     if (priority == 0)
   6205         control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
   6206     else
   6207         control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
   6208 
   6209     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6210         DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
   6211                 priority == 0 ? "ENABLE" : "DISABLE");
   6212         return false;
   6213     }
   6214     return true;
   6215 }
   6216 
   6217 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
   6218     struct v4l2_control control;
   6219 
   6220     control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
   6221     control.value = rate;
   6222 
   6223     DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
   6224     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   6225 
   6226     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6227         hw_overload = errno == EBUSY;
   6228         DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
   6229                 rate >> 16, hw_overload ? "HW overload" : strerror(errno));
   6230         return false;
   6231     }
   6232     operating_rate = rate;
   6233     DEBUG_PRINT_LOW("Operating Rate Set = %d fps",  rate >> 16);
   6234     return true;
   6235 }
   6236 
   6237 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
   6238     char *userptr;
   6239     int fd;
   6240     unsigned offset;
   6241     ssize_t size;
   6242     struct msm_vidc_roi_qp_payload *roiData;
   6243     if (!roiInfo) {
   6244         DEBUG_PRINT_ERROR("No ROI info present");
   6245         return false;
   6246     }
   6247     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
   6248         m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
   6249         DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
   6250         return false;
   6251     }
   6252 
   6253     venc_roiqp_log_buffers(roiInfo);
   6254     mInputExtradata.getForConfig(&userptr, &fd, &offset, &size);
   6255     if (!userptr || size < roiInfo->nRoiMBInfoSize) {
   6256         DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize);
   6257         return false;
   6258     }
   6259 
   6260     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr;
   6261     data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
   6262     data->nVersion.nVersion = OMX_SPEC_VERSION;
   6263     data->nPortIndex = 0;
   6264     data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
   6265     data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
   6266 
   6267     roiData = (struct msm_vidc_roi_qp_payload *)(data->data);
   6268     roiData->upper_qp_offset = roiInfo->nUpperQpOffset;
   6269     roiData->lower_qp_offset = roiInfo->nLowerQpOffset;
   6270     roiData->b_roi_info = roiInfo->bUseRoiInfo;
   6271     roiData->mbi_info_size = roiInfo->nRoiMBInfoSize;
   6272     memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize);
   6273 
   6274     data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   6275     data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
   6276     data->nVersion.nVersion = OMX_SPEC_VERSION;
   6277     data->nPortIndex = 0;
   6278     data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE;
   6279     data->nDataSize = 0;
   6280     return true;
   6281 }
   6282 
   6283 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
   6284         OMX_U32 *nMaxBLayers) {
   6285 
   6286     // no B-layers for all cases
   6287     temporal_layers_config.nMaxBLayers = 0;
   6288     temporal_layers_config.nMaxLayers = 1;
   6289 
   6290     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
   6291             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   6292         temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
   6293     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   6294         temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
   6295     }
   6296 
   6297     *nMaxLayers = temporal_layers_config.nMaxLayers;
   6298     *nMaxBLayers = temporal_layers_config.nMaxBLayers;
   6299     return true;
   6300 }
   6301 
   6302 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
   6303         OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
   6304 
   6305     if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
   6306             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
   6307             || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
   6308         DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
   6309         return OMX_ErrorUnsupportedSetting;
   6310     }
   6311 
   6312     if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
   6313             (pTemporalParams->nBLayerCountActual != 0 ||
   6314              pTemporalParams->nPLayerCountActual != 1)) {
   6315         return OMX_ErrorBadParameter;
   6316     } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
   6317             pTemporalParams->nPLayerCountActual < 1) {
   6318         return OMX_ErrorBadParameter;
   6319     }
   6320 
   6321     if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
   6322         DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
   6323                 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
   6324         return OMX_ErrorBadParameter;
   6325     } else if (pTemporalParams->nPLayerCountActual >
   6326              temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
   6327         DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
   6328                 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
   6329                 temporal_layers_config.nMaxLayers);
   6330         return OMX_ErrorBadParameter;
   6331     }
   6332 
   6333     // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
   6334     // use hybrid-HP for best results
   6335     bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
   6336     bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
   6337     bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
   6338 
   6339     // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
   6340     bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
   6341 
   6342     DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
   6343             rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
   6344 
   6345     if (bUseHybridMode &&
   6346             !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
   6347                 pTemporalParams->nBLayerCountActual,
   6348                 0 /* LTR count */, (int) HIER_P_HYBRID)) {
   6349         bUseHybridMode = false;
   6350         DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
   6351     }
   6352 
   6353     if (intra_period.num_bframes) {
   6354         DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
   6355         return OMX_ErrorUnsupportedSetting;
   6356     }
   6357 
   6358     if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
   6359         DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
   6360                 intra_period.num_pframes, intra_period.num_bframes);
   6361         return OMX_ErrorUnsupportedSetting;
   6362     }
   6363 
   6364     struct v4l2_control control;
   6365     // Num enhancements layers does not include the base-layer
   6366     control.value = pTemporalParams->nPLayerCountActual - 1;
   6367 
   6368     if (bUseHybridMode) {
   6369         DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
   6370         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
   6371         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6372             bUseHybridMode = false;
   6373             DEBUG_PRINT_ERROR("Failed to set hybrid HP");
   6374         } else {
   6375             // Disable normal HP if Hybrid mode is being enabled
   6376             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
   6377             control.value = 0;
   6378             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6379                 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
   6380                 return OMX_ErrorUnsupportedSetting;
   6381             }
   6382             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
   6383             control.value = 0;
   6384             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6385                 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
   6386                 return OMX_ErrorUnsupportedSetting;
   6387             }
   6388         }
   6389     }
   6390 
   6391     if (!bUseHybridMode) {
   6392 
   6393         // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
   6394         if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
   6395             DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
   6396             return OMX_ErrorUnsupportedSetting;
   6397         }
   6398 
   6399         DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
   6400         control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
   6401         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6402             DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
   6403             return OMX_ErrorUnsupportedSetting;
   6404         }
   6405 
   6406         // configure max layers for a session.. Okay to use current num-layers as max
   6407         //  since we do not plan to support dynamic changes to number of layers
   6408         control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
   6409         control.value = pTemporalParams->nPLayerCountActual - 1;
   6410         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6411             DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
   6412             return OMX_ErrorUnsupportedSetting;
   6413 
   6414         } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
   6415             // Disable hybrid mode if it was enabled already
   6416             DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
   6417             control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
   6418             control.value = 0;
   6419             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6420                 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
   6421                 return OMX_ErrorUnsupportedSetting;
   6422             }
   6423         }
   6424     }
   6425 
   6426     // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
   6427     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   6428         DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
   6429         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
   6430         control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
   6431         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   6432             DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
   6433             return OMX_ErrorUnsupportedSetting;
   6434         }
   6435     }
   6436 
   6437     temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
   6438     temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
   6439     temporal_layers_config.nBLayers = 0;
   6440 
   6441     temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
   6442     if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
   6443         DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
   6444         return OMX_ErrorNone;
   6445     }
   6446     DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
   6447 
   6448     OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
   6449             numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
   6450 
   6451     OMX_U32 i = 0;
   6452     for (; i < numLayers; ++i) {
   6453         OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
   6454         OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
   6455         if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
   6456             DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
   6457             return OMX_ErrorBadParameter;
   6458         } else {
   6459             layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
   6460             temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
   6461             temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
   6462             DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
   6463                     i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
   6464         }
   6465     }
   6466 
   6467     temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
   6468 
   6469     // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
   6470     if (bitrate.target_bitrate > 0) {
   6471         if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
   6472             return OMX_ErrorUnsupportedSetting;
   6473         }
   6474     } else {
   6475         DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
   6476     }
   6477 
   6478     return OMX_ErrorNone;
   6479 }
   6480 
   6481 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
   6482     OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
   6483     memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
   6484 
   6485     if (!temporal_layers_config.nPLayers) {
   6486         return OMX_ErrorNone;
   6487     }
   6488     pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
   6489     pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
   6490     pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
   6491     pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
   6492     pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
   6493     pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
   6494     pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
   6495     if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
   6496         for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
   6497             pTemporalParams.nBitrateRatios[i] =
   6498                     temporal_layers_config.nTemporalLayerBitrateRatio[i];
   6499         }
   6500     }
   6501     return venc_set_temporal_layers(&pTemporalParams);
   6502 }
   6503 
   6504 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
   6505 {
   6506     bool status = true;
   6507 
   6508     if (eProfile == NULL || eLevel == NULL) {
   6509         return false;
   6510     }
   6511 
   6512     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   6513         switch (codec_profile.profile) {
   6514             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
   6515                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   6516                 break;
   6517             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
   6518                 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   6519                 break;
   6520             default:
   6521                 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
   6522                 status = false;
   6523                 break;
   6524         }
   6525 
   6526         if (!status) {
   6527             return status;
   6528         }
   6529 
   6530         //profile level
   6531         switch (profile_level.level) {
   6532             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
   6533                 *eLevel = OMX_VIDEO_MPEG4Level0;
   6534                 break;
   6535             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
   6536                 *eLevel = OMX_VIDEO_MPEG4Level0b;
   6537                 break;
   6538             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
   6539                 *eLevel = OMX_VIDEO_MPEG4Level1;
   6540                 break;
   6541             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
   6542                 *eLevel = OMX_VIDEO_MPEG4Level2;
   6543                 break;
   6544             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
   6545                 *eLevel = OMX_VIDEO_MPEG4Level3;
   6546                 break;
   6547             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
   6548                 *eLevel = OMX_VIDEO_MPEG4Level4;
   6549                 break;
   6550             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
   6551                 *eLevel = OMX_VIDEO_MPEG4Level5;
   6552                 break;
   6553             default:
   6554                 *eLevel = OMX_VIDEO_MPEG4LevelMax;
   6555                 status =  false;
   6556                 break;
   6557         }
   6558     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   6559         if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
   6560             *eProfile = OMX_VIDEO_H263ProfileBaseline;
   6561         } else {
   6562             *eProfile = OMX_VIDEO_H263ProfileMax;
   6563             return false;
   6564         }
   6565 
   6566         switch (profile_level.level) {
   6567             case VEN_LEVEL_H263_10:
   6568                 *eLevel = OMX_VIDEO_H263Level10;
   6569                 break;
   6570             case VEN_LEVEL_H263_20:
   6571                 *eLevel = OMX_VIDEO_H263Level20;
   6572                 break;
   6573             case VEN_LEVEL_H263_30:
   6574                 *eLevel = OMX_VIDEO_H263Level30;
   6575                 break;
   6576             case VEN_LEVEL_H263_40:
   6577                 *eLevel = OMX_VIDEO_H263Level40;
   6578                 break;
   6579             case VEN_LEVEL_H263_45:
   6580                 *eLevel = OMX_VIDEO_H263Level45;
   6581                 break;
   6582             case VEN_LEVEL_H263_50:
   6583                 *eLevel = OMX_VIDEO_H263Level50;
   6584                 break;
   6585             case VEN_LEVEL_H263_60:
   6586                 *eLevel = OMX_VIDEO_H263Level60;
   6587                 break;
   6588             case VEN_LEVEL_H263_70:
   6589                 *eLevel = OMX_VIDEO_H263Level70;
   6590                 break;
   6591             default:
   6592                 *eLevel = OMX_VIDEO_H263LevelMax;
   6593                 status = false;
   6594                 break;
   6595         }
   6596     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   6597         switch (codec_profile.profile) {
   6598             case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   6599                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
   6600                 break;
   6601             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   6602                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   6603                 break;
   6604             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
   6605                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
   6606                 break;
   6607             case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   6608                 *eProfile = OMX_VIDEO_AVCProfileMain;
   6609                 break;
   6610             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   6611                 *eProfile = OMX_VIDEO_AVCProfileHigh;
   6612                 break;
   6613             case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   6614                 *eProfile = OMX_VIDEO_AVCProfileExtended;
   6615                 break;
   6616             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   6617                 *eProfile = OMX_VIDEO_AVCProfileHigh10;
   6618                 break;
   6619             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   6620                 *eProfile = OMX_VIDEO_AVCProfileHigh422;
   6621                 break;
   6622             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   6623                 *eProfile = OMX_VIDEO_AVCProfileHigh444;
   6624                 break;
   6625             default:
   6626                 *eProfile = OMX_VIDEO_AVCProfileMax;
   6627                 status = false;
   6628                 break;
   6629         }
   6630 
   6631         if (!status) {
   6632             return status;
   6633         }
   6634 
   6635         switch (profile_level.level) {
   6636             case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
   6637                 *eLevel = OMX_VIDEO_AVCLevel1;
   6638                 break;
   6639             case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
   6640                 *eLevel = OMX_VIDEO_AVCLevel1b;
   6641                 break;
   6642             case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
   6643                 *eLevel = OMX_VIDEO_AVCLevel11;
   6644                 break;
   6645             case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
   6646                 *eLevel = OMX_VIDEO_AVCLevel12;
   6647                 break;
   6648             case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
   6649                 *eLevel = OMX_VIDEO_AVCLevel13;
   6650                 break;
   6651             case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
   6652                 *eLevel = OMX_VIDEO_AVCLevel2;
   6653                 break;
   6654             case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
   6655                 *eLevel = OMX_VIDEO_AVCLevel21;
   6656                 break;
   6657             case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
   6658                 *eLevel = OMX_VIDEO_AVCLevel22;
   6659                 break;
   6660             case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
   6661                 *eLevel = OMX_VIDEO_AVCLevel3;
   6662                 break;
   6663             case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
   6664                 *eLevel = OMX_VIDEO_AVCLevel31;
   6665                 break;
   6666             case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
   6667                 *eLevel = OMX_VIDEO_AVCLevel32;
   6668                 break;
   6669             case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
   6670                 *eLevel = OMX_VIDEO_AVCLevel4;
   6671                 break;
   6672             case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
   6673                 *eLevel = OMX_VIDEO_AVCLevel41;
   6674                 break;
   6675             case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
   6676                 *eLevel = OMX_VIDEO_AVCLevel42;
   6677                 break;
   6678             case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
   6679                 *eLevel = OMX_VIDEO_AVCLevel5;
   6680                 break;
   6681             case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
   6682                 *eLevel = OMX_VIDEO_AVCLevel51;
   6683                 break;
   6684             case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
   6685                 *eLevel = OMX_VIDEO_AVCLevel52;
   6686                 break;
   6687             default :
   6688                 *eLevel = OMX_VIDEO_AVCLevelMax;
   6689                 status = false;
   6690                 break;
   6691         }
   6692     }
   6693     else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   6694         switch (codec_profile.profile) {
   6695             case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
   6696                 *eProfile = OMX_VIDEO_VP8ProfileMain;
   6697                 break;
   6698             default:
   6699                 *eProfile = OMX_VIDEO_VP8ProfileMax;
   6700                 status = false;
   6701                 break;
   6702         }
   6703         if (!status) {
   6704             return status;
   6705         }
   6706 
   6707         switch (profile_level.level) {
   6708             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
   6709                 *eLevel = OMX_VIDEO_VP8Level_Version0;
   6710                 break;
   6711             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
   6712                 *eLevel = OMX_VIDEO_VP8Level_Version1;
   6713                 break;
   6714             default:
   6715                 *eLevel = OMX_VIDEO_VP8LevelMax;
   6716                 status = false;
   6717                 break;
   6718         }
   6719     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   6720         switch (codec_profile.profile) {
   6721             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
   6722                 *eProfile = OMX_VIDEO_HEVCProfileMain;
   6723                 break;
   6724             case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
   6725                 *eProfile = OMX_VIDEO_HEVCProfileMain10;
   6726                 break;
   6727             default:
   6728                 *eProfile = OMX_VIDEO_HEVCProfileMax;
   6729                 status = false;
   6730                 break;
   6731         }
   6732         if (!status) {
   6733             return status;
   6734         }
   6735 
   6736         switch (profile_level.level) {
   6737             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
   6738                 *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
   6739                 break;
   6740             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
   6741                 *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
   6742                 break;
   6743             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
   6744                 *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
   6745                 break;
   6746             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
   6747                 *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
   6748                 break;
   6749             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
   6750                 *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
   6751                 break;
   6752             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
   6753                 *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
   6754                 break;
   6755             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
   6756                 *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
   6757                 break;
   6758             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
   6759                 *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
   6760                 break;
   6761             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
   6762                 *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
   6763                 break;
   6764             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
   6765                 *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
   6766                 break;
   6767             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
   6768                 *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
   6769                 break;
   6770             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
   6771                 *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
   6772                 break;
   6773             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
   6774                 *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
   6775                 break;
   6776             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
   6777                 *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
   6778                 break;
   6779             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
   6780                 *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
   6781                 break;
   6782             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
   6783                 *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
   6784                 break;
   6785             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
   6786                 *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
   6787                 break;
   6788             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
   6789                 *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
   6790                 break;
   6791             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
   6792                 *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
   6793                 break;
   6794             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
   6795                 *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
   6796                 break;
   6797             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
   6798                 *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
   6799                 break;
   6800             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
   6801                 *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
   6802                 break;
   6803             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
   6804                 *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
   6805                 break;
   6806             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
   6807                 *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
   6808                 break;
   6809             case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
   6810                 *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
   6811                 break;
   6812             default:
   6813                 *eLevel = OMX_VIDEO_HEVCLevelMax;
   6814                 status = false;
   6815                 break;
   6816         }
   6817     }
   6818 
   6819     return status;
   6820 }
   6821 
   6822 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
   6823 {
   6824     OMX_U32 new_profile = 0, new_level = 0;
   6825     unsigned const int *profile_tbl = NULL;
   6826     OMX_U32 mb_per_frame, mb_per_sec;
   6827     bool profile_level_found = false;
   6828 
   6829     DEBUG_PRINT_LOW("Init profile table for respective codec");
   6830 
   6831     //validate the ht,width,fps,bitrate and set the appropriate profile and level
   6832     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   6833         if (*eProfile == 0) {
   6834             if (!m_profile_set) {
   6835                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   6836             } else {
   6837                 switch (codec_profile.profile) {
   6838                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
   6839                         *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   6840                         break;
   6841                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
   6842                         *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   6843                         break;
   6844                     default:
   6845                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
   6846                         return false;
   6847                 }
   6848             }
   6849         }
   6850 
   6851         if (*eLevel == 0 && !m_level_set) {
   6852             *eLevel = OMX_VIDEO_MPEG4LevelMax;
   6853         }
   6854 
   6855         if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
   6856             profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
   6857         } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
   6858             profile_tbl = (unsigned int const *)
   6859                 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   6860         } else {
   6861             DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
   6862             return false;
   6863         }
   6864     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   6865         if (*eProfile == 0) {
   6866             if (!m_profile_set) {
   6867                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
   6868             } else {
   6869                 switch (codec_profile.profile) {
   6870                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   6871                         *eProfile = OMX_VIDEO_AVCProfileBaseline;
   6872                         break;
   6873                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   6874                         *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   6875                         break;
   6876                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
   6877                          *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
   6878                         break;
   6879                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   6880                         *eProfile = OMX_VIDEO_AVCProfileMain;
   6881                         break;
   6882                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   6883                         *eProfile = OMX_VIDEO_AVCProfileExtended;
   6884                         break;
   6885                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   6886                         *eProfile = OMX_VIDEO_AVCProfileHigh;
   6887                         break;
   6888                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   6889                         *eProfile = OMX_VIDEO_AVCProfileHigh10;
   6890                         break;
   6891                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   6892                         *eProfile = OMX_VIDEO_AVCProfileHigh422;
   6893                         break;
   6894                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   6895                         *eProfile = OMX_VIDEO_AVCProfileHigh444;
   6896                         break;
   6897                     default:
   6898                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
   6899                         return false;
   6900                 }
   6901             }
   6902         }
   6903 
   6904         if (*eLevel == 0 && !m_level_set) {
   6905             *eLevel = OMX_VIDEO_AVCLevelMax;
   6906         }
   6907 
   6908         if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
   6909             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
   6910             profile_tbl = (unsigned int const *)h264_profile_level_table;
   6911         } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
   6912             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
   6913             profile_tbl = (unsigned int const *)
   6914                 (&h264_profile_level_table[H264_HP_START]);
   6915         } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
   6916             profile_tbl = (unsigned int const *)
   6917                 (&h264_profile_level_table[H264_MP_START]);
   6918         } else {
   6919             DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
   6920             return false;
   6921         }
   6922     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   6923         if (*eProfile == 0) {
   6924             if (!m_profile_set) {
   6925                 *eProfile = OMX_VIDEO_H263ProfileBaseline;
   6926             } else {
   6927                 switch (codec_profile.profile) {
   6928                     case VEN_PROFILE_H263_BASELINE:
   6929                         *eProfile = OMX_VIDEO_H263ProfileBaseline;
   6930                         break;
   6931                     default:
   6932                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
   6933                         return false;
   6934                 }
   6935             }
   6936         }
   6937 
   6938         if (*eLevel == 0 && !m_level_set) {
   6939             *eLevel = OMX_VIDEO_H263LevelMax;
   6940         }
   6941 
   6942         if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
   6943             profile_tbl = (unsigned int const *)h263_profile_level_table;
   6944         } else {
   6945             DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
   6946             return false;
   6947         }
   6948     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   6949         if (*eProfile == 0) {
   6950             *eProfile = OMX_VIDEO_VP8ProfileMain;
   6951         } else {
   6952             switch (codec_profile.profile) {
   6953                 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
   6954                     *eProfile = OMX_VIDEO_VP8ProfileMain;
   6955                     break;
   6956                 default:
   6957                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
   6958                     return false;
   6959             }
   6960         }
   6961         if (*eLevel == 0) {
   6962             switch (profile_level.level) {
   6963                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
   6964                     *eLevel = OMX_VIDEO_VP8Level_Version0;
   6965                     break;
   6966                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
   6967                     *eLevel = OMX_VIDEO_VP8Level_Version1;
   6968                     break;
   6969                 default:
   6970                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
   6971                     return false;
   6972             }
   6973         }
   6974         return true;
   6975     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
   6976         if (*eProfile == 0) {
   6977             if (!m_profile_set) {
   6978                 *eProfile = OMX_VIDEO_HEVCProfileMain;
   6979             } else {
   6980                 switch (codec_profile.profile) {
   6981                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
   6982                         *eProfile = OMX_VIDEO_HEVCProfileMain;
   6983                         break;
   6984                     case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
   6985                         *eProfile = OMX_VIDEO_HEVCProfileMain10;
   6986                         break;
   6987                     default:
   6988                         DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
   6989                         return false;
   6990                 }
   6991             }
   6992         }
   6993 
   6994         if (*eLevel == 0 && !m_level_set) {
   6995             *eLevel = OMX_VIDEO_HEVCLevelMax;
   6996         }
   6997 
   6998         if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
   6999             profile_tbl = (unsigned int const *)hevc_profile_level_table;
   7000         } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
   7001             profile_tbl = (unsigned int const *)
   7002                 (&hevc_profile_level_table[HEVC_MAIN10_START]);
   7003         } else {
   7004             DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
   7005             return false;
   7006         }
   7007     } else {
   7008         DEBUG_PRINT_ERROR("Invalid codec type");
   7009         return false;
   7010     }
   7011 
   7012     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
   7013         ((m_sVenc_cfg.dvs_width + 15)>> 4);
   7014 
   7015     if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
   7016         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
   7017             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   7018 
   7019         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
   7020             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   7021 
   7022         {
   7023             new_level = profile_level.level;
   7024             new_profile = codec_profile.profile;
   7025             return true;
   7026         }
   7027     }
   7028 
   7029     if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
   7030         *eLevel = rc_off_level; //No level calculation for RC_OFF
   7031         profile_level_found = true;
   7032         return true;
   7033     }
   7034 
   7035     mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
   7036 
   7037     bool h264, ltr, hlayers;
   7038     unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
   7039     h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
   7040     ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
   7041     hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
   7042      ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
   7043 
   7044     /*  Hybrid HP reference buffers:
   7045         layers = 1, 2 need 1 reference buffer
   7046         layers = 3, 4 need 2 reference buffers
   7047         layers = 5, 6 need 3 reference buffers
   7048     */
   7049 
   7050     if(hier_layers.hier_mode == HIER_P_HYBRID)
   7051         hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
   7052 
   7053     do {
   7054         if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
   7055             if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
   7056                 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
   7057                     if (h264 && (ltr || hlayers || hybridp)) {
   7058                         // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
   7059                         new_level = (int)profile_tbl[3];
   7060                         new_profile = (int)profile_tbl[4];
   7061                         profile_level_found = true;
   7062                         DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
   7063                                         ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
   7064                                         MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
   7065                         break;
   7066                     } else {
   7067                         new_level = (int)profile_tbl[3];
   7068                         new_profile = (int)profile_tbl[4];
   7069                         profile_level_found = true;
   7070                         DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
   7071                         break;
   7072                     }
   7073                 }
   7074             }
   7075         }
   7076         profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
   7077     } while (profile_tbl[0] != 0);
   7078 
   7079     if (profile_level_found != true) {
   7080         DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
   7081         return false;
   7082     }
   7083 
   7084     if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
   7085             || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
   7086             || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
   7087         *eLevel = new_level;
   7088     }
   7089 
   7090     DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
   7091             "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
   7092 
   7093     return true;
   7094 }
   7095 #ifdef _ANDROID_ICS_
   7096 bool venc_dev::venc_set_meta_mode(bool mode)
   7097 {
   7098     metadatamode = mode;
   7099     return true;
   7100 }
   7101 #endif
   7102 
   7103 bool venc_dev::venc_is_video_session_supported(unsigned long width,
   7104         unsigned long height)
   7105 {
   7106     if ((width * height < capability.min_width *  capability.min_height) ||
   7107             (width * height > capability.max_width *  capability.max_height)) {
   7108         DEBUG_PRINT_ERROR(
   7109                 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
   7110                 width, height, capability.min_width, capability.min_height,
   7111                 capability.max_width, capability.max_height);
   7112         return false;
   7113     }
   7114 
   7115     DEBUG_PRINT_LOW("video session supported");
   7116     return true;
   7117 }
   7118 
   7119 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
   7120 {
   7121     struct v4l2_control control;
   7122     int ret;
   7123 
   7124     control.id = V4L2_CID_VIDC_QBUF_MODE;
   7125     control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
   7126 
   7127     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   7128     if (ret) {
   7129         DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
   7130         return false;
   7131     }
   7132 
   7133     mBatchSize = batchSize;
   7134     DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
   7135     return true;
   7136 }
   7137 
   7138 venc_dev::BatchInfo::BatchInfo()
   7139     : mNumPending(0) {
   7140     pthread_mutex_init(&mLock, NULL);
   7141     for (int i = 0; i < kMaxBufs; ++i) {
   7142         mBufMap[i] = kBufIDFree;
   7143     }
   7144 }
   7145 
   7146 int venc_dev::BatchInfo::registerBuffer(int bufferId) {
   7147     pthread_mutex_lock(&mLock);
   7148     int availId = 0;
   7149     for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
   7150     if (availId >= kMaxBufs) {
   7151         DEBUG_PRINT_ERROR("Failed to find free entry !");
   7152         pthread_mutex_unlock(&mLock);
   7153         return -1;
   7154     }
   7155     mBufMap[availId] = bufferId;
   7156     mNumPending++;
   7157     pthread_mutex_unlock(&mLock);
   7158     return availId;
   7159 }
   7160 
   7161 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
   7162     pthread_mutex_lock(&mLock);
   7163     if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
   7164         DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
   7165         pthread_mutex_unlock(&mLock);
   7166         return -1;
   7167     }
   7168     if (mBufMap[v4l2Id] == kBufIDFree) {
   7169         DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
   7170         pthread_mutex_unlock(&mLock);
   7171         return -1;
   7172     }
   7173     int bufferId = mBufMap[v4l2Id];
   7174     mBufMap[v4l2Id] = kBufIDFree;
   7175     mNumPending--;
   7176     pthread_mutex_unlock(&mLock);
   7177     return bufferId;
   7178 }
   7179 
   7180 bool venc_dev::BatchInfo::isPending(int bufferId) {
   7181     pthread_mutex_lock(&mLock);
   7182     int existsId = 0;
   7183     for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
   7184     pthread_mutex_unlock(&mLock);
   7185     return existsId < kMaxBufs;
   7186 }
   7187 
   7188 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
   7189     int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
   7190     return fd;
   7191 }
   7192 
   7193 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
   7194     int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
   7195     return off;
   7196 }
   7197 
   7198 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
   7199     int size = hnd && (index + hnd->numFds) < hnd->numInts ?
   7200             hnd->data[2*hnd->numFds + index] : -1;
   7201     return size;
   7202 }
   7203 
   7204 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
   7205     int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
   7206             hnd->data[3*hnd->numFds + index] : 0;
   7207     return usage;
   7208 }
   7209 
   7210 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
   7211     int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
   7212             hnd->data[4*hnd->numFds + index] : -1;
   7213     return size;
   7214 }
   7215 
   7216 #ifdef _VQZIP_
   7217 venc_dev::venc_dev_vqzip::venc_dev_vqzip()
   7218 {
   7219     mLibHandle = NULL;
   7220     pthread_mutex_init(&lock, NULL);
   7221 }
   7222 
   7223 bool venc_dev::venc_dev_vqzip::init()
   7224 {
   7225     bool status = true;
   7226     if (mLibHandle) {
   7227         DEBUG_PRINT_ERROR("VQZIP init called twice");
   7228         status = false;
   7229     }
   7230     if (status) {
   7231         mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
   7232         if (mLibHandle) {
   7233             mVQZIPInit = (vqzip_init_t)
   7234                 dlsym(mLibHandle,"VQZipInit");
   7235             mVQZIPDeInit = (vqzip_deinit_t)
   7236                 dlsym(mLibHandle,"VQZipDeInit");
   7237             mVQZIPComputeStats = (vqzip_compute_stats_t)
   7238                 dlsym(mLibHandle,"VQZipComputeStats");
   7239             if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
   7240                 status = false;
   7241         } else {
   7242             DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
   7243             status = false;
   7244         }
   7245         if (status) {
   7246             mVQZIPHandle = mVQZIPInit();
   7247         }
   7248     }
   7249     if (!status && mLibHandle) {
   7250         dlclose(mLibHandle);
   7251         mLibHandle = NULL;
   7252         mVQZIPHandle = NULL;
   7253         mVQZIPInit = NULL;
   7254         mVQZIPDeInit = NULL;
   7255         mVQZIPComputeStats = NULL;
   7256     }
   7257     return status;
   7258 }
   7259 
   7260 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
   7261 {
   7262     VQZipStatus result;
   7263     VQZipStats *pStats = (VQZipStats *)extraData;
   7264     pConfig.pSEIPayload = NULL;
   7265     unsigned long size;
   7266 
   7267     if (!pBuf || !pStats || !mVQZIPHandle) {
   7268         DEBUG_PRINT_ERROR("Invalid data passed to stats function");
   7269     }
   7270     result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
   7271     return (result < 0);
   7272 }
   7273 
   7274 void venc_dev::venc_dev_vqzip::deinit()
   7275 {
   7276     if (mLibHandle) {
   7277         pthread_mutex_lock(&lock);
   7278         dlclose(mLibHandle);
   7279         mVQZIPDeInit(mVQZIPHandle);
   7280         mLibHandle = NULL;
   7281         mVQZIPHandle = NULL;
   7282         mVQZIPInit = NULL;
   7283         mVQZIPDeInit = NULL;
   7284         mVQZIPComputeStats = NULL;
   7285         pthread_mutex_unlock(&lock);
   7286     }
   7287 }
   7288 
   7289 venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
   7290 {
   7291     DEBUG_PRINT_HIGH("Destroy C2D instance");
   7292     if (mLibHandle) {
   7293         dlclose(mLibHandle);
   7294     }
   7295     mLibHandle = NULL;
   7296     pthread_mutex_destroy(&lock);
   7297 }
   7298 #endif
   7299 
   7300 encExtradata::encExtradata(class omx_venc *venc_handle)
   7301 {
   7302     mCount = 0;
   7303     mSize = 0;
   7304     mUaddr = NULL;
   7305     memset(&mIon, -1, sizeof(struct venc_ion));
   7306     memset(mIndex, 0, sizeof(mIndex));
   7307     mVencHandle = venc_handle;
   7308     mDbgEtbCount = 0;
   7309     pthread_mutex_init(&lock, NULL);
   7310     vqzip_sei_found = false;
   7311 }
   7312 
   7313 encExtradata::~encExtradata()
   7314 {
   7315     __free();
   7316     mCount = 0;
   7317     mSize = 0;
   7318     mVencHandle = NULL;
   7319     pthread_mutex_destroy(&lock);
   7320 }
   7321 
   7322 OMX_ERRORTYPE encExtradata::__allocate()
   7323 {
   7324     ssize_t totalSize = (mSize * mCount + 4095) & (~4095);
   7325     if (!mVencHandle) {
   7326         return OMX_ErrorInsufficientResources;
   7327     }
   7328     if (mUaddr || !totalSize) {
   7329         return OMX_ErrorNone;
   7330     }
   7331     mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory(
   7332             totalSize,
   7333             &mIon.ion_alloc_data,
   7334             &mIon.fd_ion_data, 0);
   7335     if (mIon.ion_device_fd < 0) {
   7336         DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize);
   7337         DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set.");
   7338         return OMX_ErrorInsufficientResources;
   7339     }
   7340     mUaddr = (char *)mmap(NULL, totalSize,
   7341             PROT_READ|PROT_WRITE, MAP_SHARED,
   7342             mIon.fd_ion_data.fd , 0);
   7343     if (mUaddr == MAP_FAILED) {
   7344         DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
   7345         close(mIon.fd_ion_data.fd);
   7346         mVencHandle->free_ion_memory(&mIon);
   7347         return OMX_ErrorInsufficientResources;
   7348     }
   7349     for (unsigned i = 0; i < mCount; i++) {
   7350         mIndex[i].status = FREE;
   7351         mIndex[i].cookie = NULL;
   7352     }
   7353     return OMX_ErrorNone;
   7354 }
   7355 
   7356 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type)
   7357 {
   7358     unsigned i = 0;
   7359     if (__allocate() != OMX_ErrorNone) {
   7360         return -1;
   7361     }
   7362     for (i = 0; i < mCount; i++) {
   7363         if (mIndex[i].status == type) {
   7364             mIndex[i].status = BUSY;
   7365             break;
   7366         }
   7367     }
   7368     if (i >= mCount) {
   7369         DEBUG_PRINT_HIGH("No Free extradata available");
   7370         return -1;
   7371     }
   7372     *userptr = mUaddr + i * mSize;
   7373     *fd = mIon.fd_ion_data.fd;
   7374     *offset = i * mSize;
   7375     *size = mSize;
   7376     return i;
   7377 }
   7378 
   7379 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) {
   7380     int index;
   7381     *userptr = NULL;
   7382     *fd = -1;
   7383     *offset = 0;
   7384     *size = 0;
   7385     pthread_mutex_lock(&lock);
   7386     index = __get(userptr, fd, offset, size, FREE);
   7387     DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
   7388     pthread_mutex_unlock(&lock);
   7389     return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone;
   7390 }
   7391 
   7392 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size)
   7393 {
   7394     OMX_ERRORTYPE rc = OMX_ErrorNone;
   7395     unsigned int i;
   7396     *userptr = NULL;
   7397     *fd = -1;
   7398     *offset = 0;
   7399     *size = 0;
   7400     pthread_mutex_lock(&lock);
   7401     for (i = 0; i < mCount; i++) {
   7402         if (mIndex[i].cookie == cookie) {
   7403             break;
   7404         }
   7405     }
   7406     if (i < mCount) {
   7407         *userptr = mUaddr + i * mSize;
   7408         *fd = mIon.fd_ion_data.fd;
   7409         *offset = i * mSize;
   7410         *size = mSize;
   7411     } else {
   7412         int index = __get(userptr, fd, offset, size, FREE);
   7413         if (index < 0 ) {
   7414             DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie);
   7415             __debug();
   7416             rc = OMX_ErrorInsufficientResources;
   7417         }
   7418     }
   7419     DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size);
   7420     pthread_mutex_unlock(&lock);
   7421     return rc;
   7422 }
   7423 
   7424 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size)
   7425 {
   7426     OMX_ERRORTYPE rc = OMX_ErrorNone;
   7427     unsigned int i;
   7428     int found = -1;
   7429     pthread_mutex_lock(&lock);
   7430     found = __get(userptr, fd, offset, size, FOR_CONFIG);
   7431     if (found < 0) {
   7432         found = __get(userptr, fd, offset, size, FREE);
   7433     }
   7434 
   7435     if (found < 0) {
   7436         DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found);
   7437         __debug();
   7438         rc = OMX_ErrorInsufficientResources;
   7439     } else {
   7440         mIndex[found].status = FOR_CONFIG;
   7441         DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size);
   7442     }
   7443     pthread_mutex_unlock(&lock);
   7444     return rc;
   7445 }
   7446 
   7447 OMX_ERRORTYPE encExtradata::put(char *userptr)
   7448 {
   7449     OMX_ERRORTYPE rc = OMX_ErrorNone;
   7450     int index = (userptr - mUaddr)/mSize;
   7451     pthread_mutex_lock(&lock);
   7452     if (!userptr) {
   7453         DEBUG_PRINT_HIGH("Userptr is NULL");
   7454         rc = OMX_ErrorBadParameter;
   7455     } else if (index < 0) {
   7456         DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr);
   7457         __debug();
   7458         rc = OMX_ErrorBadParameter;
   7459     } else {
   7460         mIndex[index].status = FREE;
   7461         mIndex[index].cookie = NULL;
   7462         DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr);
   7463     }
   7464     pthread_mutex_unlock(&lock);
   7465     return rc;
   7466 }
   7467 
   7468 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size)
   7469 {
   7470     OMX_ERRORTYPE rc = OMX_ErrorNone;
   7471     *userptr = 0;
   7472     *fd = -1;
   7473     *offset = 0;
   7474     *size = 0;
   7475     pthread_mutex_lock(&lock);
   7476     if (index < mCount) {
   7477         rc = __allocate();
   7478         if (rc == OMX_ErrorNone) {
   7479             *userptr = mUaddr + index * mSize;
   7480             *fd = mIon.fd_ion_data.fd;
   7481             *offset = index * mSize;
   7482             *size = mSize;
   7483         }
   7484     }
   7485     DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size);
   7486     pthread_mutex_unlock(&lock);
   7487     return rc;
   7488 }
   7489 
   7490 void encExtradata::setCookieForConfig(void *cookie)
   7491 {
   7492     char *userptr;
   7493     int fd;
   7494     unsigned offset;
   7495     ssize_t size;
   7496     pthread_mutex_lock(&lock);
   7497     int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG);
   7498     if (found >= 0) {
   7499         mIndex[found].cookie = cookie;
   7500     } else {
   7501         DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n",
   7502             found, cookie);
   7503         __debug();
   7504     }
   7505     mDbgEtbCount++;
   7506     pthread_mutex_unlock(&lock);
   7507 }
   7508 
   7509 void encExtradata::__free()
   7510 {
   7511     ssize_t totalSize = (mCount * mSize + 4095) & (~4095);
   7512     if (mUaddr) {
   7513         munmap((void *)mUaddr, totalSize);
   7514         mUaddr = NULL;
   7515     }
   7516     if (mIon.fd_ion_data.fd >= 0) {
   7517         if (mVencHandle)
   7518             mVencHandle->free_ion_memory(&mIon);
   7519         close(mIon.fd_ion_data.fd);
   7520         mIon.fd_ion_data.fd = -1;
   7521     }
   7522     for (unsigned i = 0; i < mCount; i++) {
   7523         mIndex[i].status = FREE;
   7524         mIndex[i].cookie = NULL;
   7525     }
   7526 }
   7527 
   7528 void encExtradata::update(unsigned int count, ssize_t size)
   7529 {
   7530     pthread_mutex_lock(&lock);
   7531     __free();
   7532     mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS;
   7533     mSize = size;
   7534     DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize);
   7535     pthread_mutex_unlock(&lock);
   7536 }
   7537 
   7538 void encExtradata::__debug()
   7539 {
   7540     DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p",
   7541             this, mCount, mSize, mUaddr, mVencHandle);
   7542     for (unsigned i = 0; i < mCount; i++) {
   7543         DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie);
   7544     }
   7545 }
   7546 
   7547 ssize_t encExtradata::getBufferSize()
   7548 {
   7549     return mSize;
   7550 }
   7551 
   7552 unsigned int encExtradata::getBufferCount()
   7553 {
   7554     return mCount;
   7555 }
   7556