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