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