Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010-2014, 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 <unistd.h>
     33 #include <fcntl.h>
     34 #include "video_encoder_device_v4l2.h"
     35 #include "omx_video_encoder.h"
     36 #include <media/msm_vidc.h>
     37 #ifdef USE_ION
     38 #include <linux/msm_ion.h>
     39 #endif
     40 #include <media/msm_media_info.h>
     41 #include <cutils/properties.h>
     42 #include <media/hardware/HardwareAPI.h>
     43 
     44 #ifdef _ANDROID_
     45 #include <media/hardware/HardwareAPI.h>
     46 #include <gralloc_priv.h>
     47 #endif
     48 
     49 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
     50 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
     51 
     52 #define MPEG4_SP_START 0
     53 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
     54 #define H263_BP_START 0
     55 #define H264_BP_START 0
     56 #define H264_HP_START (H264_BP_START + 17)
     57 #define H264_MP_START (H264_BP_START + 34)
     58 #define POLL_TIMEOUT 1000
     59 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
     60 
     61 #define SZ_4K 0x1000
     62 #define SZ_1M 0x100000
     63 
     64 /* MPEG4 profile and level table*/
     65 static const unsigned int mpeg4_profile_level_table[][5]= {
     66     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
     67     {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
     68     {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
     69     {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
     70     {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
     71     {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
     72     {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     73     {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     74     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     75     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
     76     {0,0,0,0,0},
     77 
     78     {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     79     {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     80     {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     81     {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     82     {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     83     {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     84     {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     85     {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
     86     {0,0,0,0,0},
     87 };
     88 
     89 /* H264 profile and level table*/
     90 static const unsigned int h264_profile_level_table[][5]= {
     91     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
     92     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
     93     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
     94     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
     95     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
     96     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
     97     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
     98     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
     99     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
    100     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
    101     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
    102     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
    103     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
    104     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline},
    105     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline},
    106     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline},
    107     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline},
    108     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
    109     {0,0,0,0,0},
    110 
    111     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
    112     {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
    113     {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
    114     {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
    115     {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
    116     {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
    117     {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
    118     {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
    119     {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
    120     {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
    121     {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
    122     {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
    123     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh},
    124     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh},
    125     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh},
    126     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh},
    127     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh},
    128     {0,0,0,0,0},
    129 
    130     {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
    131     {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
    132     {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
    133     {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
    134     {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
    135     {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
    136     {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
    137     {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
    138     {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
    139     {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
    140     {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
    141     {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
    142     {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain},
    143     {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain},
    144     {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain},
    145     {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain},
    146     {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
    147     {0,0,0,0,0}
    148 
    149 };
    150 
    151 /* H263 profile and level table*/
    152 static const unsigned int h263_profile_level_table[][5]= {
    153     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
    154     {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
    155     {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
    156     {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
    157     {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
    158     {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
    159     {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
    160     {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
    161     {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    162     {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    163     {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
    164     {0,0,0,0,0}
    165 };
    166 
    167 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    168 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    169 
    170 #define BUFFER_LOG_LOC "/data/misc/media"
    171 
    172 //constructor
    173 venc_dev::venc_dev(class omx_venc *venc_class)
    174 {
    175     //nothing to do
    176     int i = 0;
    177     venc_handle = venc_class;
    178     etb = ebd = ftb = fbd = 0;
    179 
    180     for (i = 0; i < MAX_PORT; i++)
    181         streaming[i] = false;
    182 
    183     stopped = 1;
    184     paused = false;
    185     async_thread_created = false;
    186     color_format = 0;
    187     pthread_mutex_init(&pause_resume_mlock, NULL);
    188     pthread_cond_init(&pause_resume_cond, NULL);
    189     memset(&extradata_info, 0, sizeof(extradata_info));
    190     memset(&idrperiod, 0, sizeof(idrperiod));
    191     memset(&multislice, 0, sizeof(multislice));
    192     memset (&slice_mode, 0 , sizeof(slice_mode));
    193     memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg));
    194     memset(&rate_ctrl, 0, sizeof(rate_ctrl));
    195     memset(&bitrate, 0, sizeof(bitrate));
    196     memset(&intra_period, 0, sizeof(intra_period));
    197     memset(&codec_profile, 0, sizeof(codec_profile));
    198     memset(&set_param, 0, sizeof(set_param));
    199     memset(&time_inc, 0, sizeof(time_inc));
    200     memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property));
    201     memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property));
    202     memset(&session_qp, 0, sizeof(session_qp));
    203     memset(&entropy, 0, sizeof(entropy));
    204     memset(&dbkfilter, 0, sizeof(dbkfilter));
    205     memset(&intra_refresh, 0, sizeof(intra_refresh));
    206     memset(&hec, 0, sizeof(hec));
    207     memset(&voptimecfg, 0, sizeof(voptimecfg));
    208     memset(&capability, 0, sizeof(capability));
    209     memset(&m_debug,0,sizeof(m_debug));
    210     memset(&hier_p_layers,0,sizeof(hier_p_layers));
    211     memset(&display_info,0,sizeof(display_info));
    212     is_searchrange_set = false;
    213     enable_mv_narrow_searchrange = false;
    214 
    215     char property_value[PROPERTY_VALUE_MAX] = {0};
    216     property_get("vidc.enc.log.in", property_value, "0");
    217     m_debug.in_buffer_log = atoi(property_value);
    218 
    219     property_get("vidc.enc.log.out", property_value, "0");
    220     m_debug.out_buffer_log = atoi(property_value);
    221 
    222     property_get("vidc.enc.log.extradata", property_value, "0");
    223     m_debug.extradata_log = atoi(property_value);
    224 
    225     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
    226              "%s", BUFFER_LOG_LOC);
    227 }
    228 
    229 venc_dev::~venc_dev()
    230 {
    231     //nothing to do
    232 }
    233 
    234 void* venc_dev::async_venc_message_thread (void *input)
    235 {
    236     struct venc_msg venc_msg;
    237     omx_video* omx_venc_base = NULL;
    238     omx_venc *omx = reinterpret_cast<omx_venc*>(input);
    239     omx_venc_base = reinterpret_cast<omx_video*>(input);
    240     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
    241 
    242     prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
    243     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    244     struct pollfd pfd;
    245     struct v4l2_buffer v4l2_buf;
    246     struct v4l2_event dqevent;
    247     pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    248     pfd.fd = omx->handle->m_nDriver_fd;
    249     int error_code = 0,rc=0;
    250 
    251     memset(&v4l2_buf, 0, sizeof(v4l2_buf));
    252 
    253     while (1) {
    254         pthread_mutex_lock(&omx->handle->pause_resume_mlock);
    255 
    256         if (omx->handle->paused) {
    257             venc_msg.msgcode = VEN_MSG_PAUSE;
    258             venc_msg.statuscode = VEN_S_SUCCESS;
    259 
    260             if (omx->async_message_process(input, &venc_msg) < 0) {
    261                 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg");
    262                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
    263                 break;
    264             }
    265 
    266             /* Block here until the IL client resumes us again */
    267             pthread_cond_wait(&omx->handle->pause_resume_cond,
    268                     &omx->handle->pause_resume_mlock);
    269 
    270             venc_msg.msgcode = VEN_MSG_RESUME;
    271             venc_msg.statuscode = VEN_S_SUCCESS;
    272 
    273             if (omx->async_message_process(input, &venc_msg) < 0) {
    274                 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg");
    275                 pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
    276                 break;
    277             }
    278         }
    279 
    280         pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
    281 
    282         rc = poll(&pfd, 1, POLL_TIMEOUT);
    283 
    284         if (!rc) {
    285             DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
    286                     omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
    287             continue;
    288         } else if (rc < 0) {
    289             DEBUG_PRINT_ERROR("Error while polling: %d", rc);
    290             break;
    291         }
    292 
    293         if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
    294             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    295             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    296             v4l2_buf.length = omx->handle->num_planes;
    297             v4l2_buf.m.planes = plane;
    298 
    299             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
    300                 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE;
    301                 venc_msg.statuscode=VEN_S_SUCCESS;
    302                 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index;
    303                 venc_msg.buf.len= v4l2_buf.m.planes->bytesused;
    304                 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset;
    305                 venc_msg.buf.flags = 0;
    306                 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer;
    307                 venc_msg.buf.clientdata=(void*)omxhdr;
    308                 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec;
    309 
    310                 /* TODO: ideally report other types of frames as well
    311                  * for now it doesn't look like IL client cares about
    312                  * other types
    313                  */
    314                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME)
    315                     venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR;
    316 
    317                 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
    318                     venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME;
    319 
    320                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
    321                     venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG;
    322 
    323                 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS)
    324                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
    325 
    326                 if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused)
    327                     venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
    328 
    329                 if (omxhdr->nFilledLen)
    330                     venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
    331 
    332                 omx->handle->fbd++;
    333 
    334                 if (omx->async_message_process(input,&venc_msg) < 0) {
    335                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    336                     break;
    337                 }
    338             }
    339         }
    340 
    341         if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
    342             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    343             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    344             v4l2_buf.m.planes = plane;
    345             v4l2_buf.length = 1;
    346 
    347             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
    348                 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
    349                 venc_msg.statuscode=VEN_S_SUCCESS;
    350                 omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index;
    351                 venc_msg.buf.clientdata=(void*)omxhdr;
    352                 omx->handle->ebd++;
    353 
    354                 if (omx->async_message_process(input,&venc_msg) < 0) {
    355                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    356                     break;
    357                 }
    358             }
    359         }
    360 
    361         if (pfd.revents & POLLPRI) {
    362             rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
    363 
    364             if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
    365                 DEBUG_PRINT_HIGH("CLOSE DONE");
    366                 break;
    367             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    368                 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE;
    369                 venc_msg.statuscode = VEN_S_SUCCESS;
    370 
    371                 if (omx->async_message_process(input,&venc_msg) < 0) {
    372                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    373                     break;
    374                 }
    375 
    376                 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE;
    377                 venc_msg.statuscode = VEN_S_SUCCESS;
    378 
    379                 if (omx->async_message_process(input,&venc_msg) < 0) {
    380                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    381                     break;
    382                 }
    383             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
    384                 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
    385                 venc_msg.msgcode = VEN_MSG_INDICATION;
    386                 venc_msg.statuscode=VEN_S_EFAIL;
    387 
    388                 if (omx->async_message_process(input,&venc_msg) < 0) {
    389                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
    390                     break;
    391                 }
    392             }
    393         }
    394     }
    395 
    396     DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
    397     return NULL;
    398 }
    399 
    400 static const int event_type[] = {
    401     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    402     V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
    403     V4L2_EVENT_MSM_VIDC_SYS_ERROR
    404 };
    405 
    406 static OMX_ERRORTYPE subscribe_to_events(int fd)
    407 {
    408     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    409     struct v4l2_event_subscription sub;
    410     int array_sz = sizeof(event_type)/sizeof(int);
    411     int i,rc;
    412     memset(&sub, 0, sizeof(sub));
    413 
    414     if (fd < 0) {
    415        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    416         return OMX_ErrorBadParameter;
    417     }
    418 
    419     for (i = 0; i < array_sz; ++i) {
    420         memset(&sub, 0, sizeof(sub));
    421         sub.type = event_type[i];
    422         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    423 
    424         if (rc) {
    425            DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
    426             break;
    427         }
    428     }
    429 
    430     if (i < array_sz) {
    431         for (--i; i >=0 ; i--) {
    432             memset(&sub, 0, sizeof(sub));
    433             sub.type = event_type[i];
    434             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    435 
    436             if (rc)
    437                DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    438         }
    439 
    440         eRet = OMX_ErrorNotImplemented;
    441     }
    442 
    443     return eRet;
    444 }
    445 
    446 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
    447 {
    448     OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
    449 
    450     if (!dst || !src)
    451         return 0;
    452 
    453     /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
    454      * targets, since the payload format will be different */
    455     mbi->nFormat = 1;
    456     mbi->nDataSize = src->data_size;
    457     memcpy(&mbi->data, &src->data, src->data_size);
    458 
    459     return mbi->nDataSize + sizeof(*mbi);
    460 }
    461 
    462 bool venc_dev::handle_extradata(void *buffer, int index)
    463 {
    464     OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
    465     OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
    466 
    467     if (!extradata_info.uaddr) {
    468         DEBUG_PRINT_ERROR("Extradata buffers not allocated");
    469         return false;
    470     }
    471 
    472     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
    473                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
    474 
    475     if (extradata_info.buffer_size >
    476             p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) {
    477         DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
    478         p_extra = NULL;
    479         return false;
    480     } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
    481         /* A lot of the code below assumes this condition, so error out if it's not met */
    482         DEBUG_PRINT_ERROR("Extradata ABI mismatch");
    483         return false;
    484     }
    485 
    486     struct msm_vidc_extradata_header *p_extradata = NULL;
    487     do {
    488         p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
    489             ((char *)p_extradata) + p_extradata->size :
    490             extradata_info.uaddr + index * extradata_info.buffer_size);
    491 
    492         switch (p_extradata->type) {
    493             case MSM_VIDC_EXTRADATA_METADATA_MBI:
    494             {
    495                 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
    496                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
    497                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
    498                 p_extra->nPortIndex = OMX_DirOutput;
    499                 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
    500                 p_extra->nDataSize = payloadSize;
    501                 break;
    502             }
    503             case MSM_VIDC_EXTRADATA_NONE:
    504                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
    505                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
    506                 p_extra->nPortIndex = OMX_DirOutput;
    507                 p_extra->eType = OMX_ExtraDataNone;
    508                 p_extra->nDataSize = 0;
    509                 break;
    510             default:
    511                 /* No idea what this stuff is, just skip over it */
    512                 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
    513                         p_extradata->type);
    514                 continue;
    515         }
    516 
    517         p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
    518     } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
    519 
    520     /* Just for debugging: Traverse the list of extra datas  and spit it out onto log */
    521     p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
    522                 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
    523     while(p_extra->eType != OMX_ExtraDataNone)
    524     {
    525         DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
    526                 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
    527                 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
    528 
    529         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
    530                 p_extra->nSize);
    531     }
    532 
    533     return true;
    534 }
    535 
    536 int venc_dev::venc_set_format(int format)
    537 {
    538     int rc = true;
    539 
    540     if (format)
    541         color_format = format;
    542     else {
    543         color_format = 0;
    544         rc = false;
    545     }
    546 
    547     return rc;
    548 }
    549 
    550 OMX_ERRORTYPE venc_dev::allocate_extradata()
    551 {
    552     if (extradata_info.allocated) {
    553         DEBUG_PRINT_ERROR("Extradata already allocated!");
    554         return OMX_ErrorNone;
    555     }
    556 
    557 #ifdef USE_ION
    558 
    559     if (extradata_info.buffer_size) {
    560         if (extradata_info.ion.ion_alloc_data.handle) {
    561             munmap((void *)extradata_info.uaddr, extradata_info.size);
    562             close(extradata_info.ion.fd_ion_data.fd);
    563             venc_handle->free_ion_memory(&extradata_info.ion);
    564         }
    565 
    566         extradata_info.size = ALIGN(extradata_info.size, SZ_4K);
    567 
    568         extradata_info.ion.ion_device_fd = venc_handle->alloc_map_ion_memory(
    569                 extradata_info.size,
    570                 &extradata_info.ion.ion_alloc_data,
    571                 &extradata_info.ion.fd_ion_data, 0);
    572 
    573         if (extradata_info.ion.ion_device_fd < 0) {
    574             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
    575             return OMX_ErrorInsufficientResources;
    576         }
    577 
    578         extradata_info.uaddr = (char *)mmap(NULL,
    579                 extradata_info.size,
    580                 PROT_READ|PROT_WRITE, MAP_SHARED,
    581                 extradata_info.ion.fd_ion_data.fd , 0);
    582 
    583         if (extradata_info.uaddr == MAP_FAILED) {
    584             DEBUG_PRINT_ERROR("Failed to map extradata memory");
    585             close(extradata_info.ion.fd_ion_data.fd);
    586             venc_handle->free_ion_memory(&extradata_info.ion);
    587             return OMX_ErrorInsufficientResources;
    588         }
    589     }
    590 
    591 #endif
    592     extradata_info.allocated = 1;
    593     return OMX_ErrorNone;
    594 }
    595 
    596 void venc_dev::free_extradata()
    597 {
    598 #ifdef USE_ION
    599 
    600     if (extradata_info.uaddr) {
    601         munmap((void *)extradata_info.uaddr, extradata_info.size);
    602         close(extradata_info.ion.fd_ion_data.fd);
    603         venc_handle->free_ion_memory(&extradata_info.ion);
    604     }
    605 
    606     memset(&extradata_info, 0, sizeof(extradata_info));
    607 #endif
    608 }
    609 
    610 bool venc_dev::venc_get_output_log_flag()
    611 {
    612     return (m_debug.out_buffer_log == 1);
    613 }
    614 
    615 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
    616 {
    617     if (!m_debug.outfile) {
    618         int size = 0;
    619         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
    620            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
    621                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    622         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
    623            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
    624                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    625         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
    626            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
    627                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    628         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
    629            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
    630                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    631         }
    632         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    633              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
    634                                 m_debug.outfile_name, size);
    635         }
    636         m_debug.outfile = fopen(m_debug.outfile_name, "ab");
    637         if (!m_debug.outfile) {
    638             DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
    639                                m_debug.outfile_name, errno);
    640             m_debug.outfile_name[0] = '\0';
    641             return -1;
    642         }
    643     }
    644     if (m_debug.outfile && buffer_len) {
    645         DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
    646         fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
    647     }
    648     return 0;
    649 }
    650 
    651 int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
    652 {
    653     if (!m_debug.extradatafile && m_debug.extradata_log) {
    654         int size = 0;
    655         if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
    656            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v",
    657                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    658         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
    659            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
    660                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    661         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
    662            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
    663                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    664         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
    665            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf",
    666                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    667         }
    668         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    669              DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
    670                                 m_debug.extradatafile_name, size);
    671         }
    672 
    673         m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
    674         if (!m_debug.extradatafile) {
    675             DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
    676                                m_debug.extradatafile_name, errno);
    677             m_debug.extradatafile_name[0] = '\0';
    678             return -1;
    679         }
    680     }
    681 
    682     if (m_debug.extradatafile) {
    683         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
    684         do {
    685             p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
    686                     ((char *)p_extra) + p_extra->nSize);
    687             fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
    688         } while (p_extra->eType != OMX_ExtraDataNone);
    689     }
    690     return 0;
    691 }
    692 
    693 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset) {
    694     if (!m_debug.infile) {
    695         int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
    696                             m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
    697         if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
    698              DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
    699                                 m_debug.infile_name, size);
    700         }
    701         m_debug.infile = fopen (m_debug.infile_name, "ab");
    702         if (!m_debug.infile) {
    703             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
    704             m_debug.infile_name[0] = '\0';
    705             return -1;
    706         }
    707     }
    708     if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
    709         unsigned long i, msize;
    710         int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
    711         int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height);
    712         unsigned char *pvirt,*ptemp;
    713 
    714         char *temp = (char *)pbuffer->pBuffer;
    715 
    716         msize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
    717         if (metadatamode == 1) {
    718             pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
    719             if (pvirt) {
    720                ptemp = pvirt;
    721                for (i = 0; i < m_sVenc_cfg.input_height; i++) {
    722                     fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
    723                     ptemp += stride;
    724                }
    725                ptemp = pvirt + (stride * scanlines);
    726                for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
    727                    fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
    728                    ptemp += stride;
    729                }
    730                munmap(pvirt, msize);
    731              } else if (pvirt == MAP_FAILED) {
    732                  DEBUG_PRINT_ERROR("%s mmap failed", __func__);
    733                  return -1;
    734              }
    735         } else {
    736             for (i = 0; i < m_sVenc_cfg.input_height; i++) {
    737                  fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
    738                  temp += stride;
    739             }
    740 
    741             temp = (char *)pbuffer->pBuffer + (stride * scanlines);
    742 
    743             for(i = 0; i < m_sVenc_cfg.input_height/2; i++) {
    744                 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile);
    745                 temp += stride;
    746             }
    747         }
    748     }
    749     return 0;
    750 }
    751 
    752 bool venc_dev::venc_open(OMX_U32 codec)
    753 {
    754     int r;
    755     unsigned int alignment = 0,buffer_size = 0, temp =0;
    756     struct v4l2_control control;
    757     OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc";
    758 
    759     char platform_name[PROPERTY_VALUE_MAX];
    760     property_get("ro.board.platform", platform_name, "0");
    761 
    762     if (!strncmp(platform_name, "msm8610", 7)) {
    763         device_name = (OMX_STRING)"/dev/video/q6_enc";
    764     }
    765     if (!strncmp(platform_name, "msm8916", 7)) {
    766         enable_mv_narrow_searchrange = true;
    767         sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
    768                         ISurfaceComposer::eDisplayIdMain));
    769         SurfaceComposerClient::getDisplayInfo(display, &display_info);
    770         DEBUG_PRINT_LOW("Display panel resolution %dX%d",
    771             display_info.w, display_info.h);
    772     }
    773     m_nDriver_fd = open (device_name, O_RDWR);
    774 
    775     if (m_nDriver_fd == 0) {
    776         DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again");
    777         m_nDriver_fd = open (device_name, O_RDWR);
    778     }
    779 
    780     if ((int)m_nDriver_fd < 0) {
    781         DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
    782         return false;
    783     }
    784 
    785     DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd);
    786     // set the basic configuration of the video encoder driver
    787     m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH;
    788     m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT;
    789     m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH;
    790     m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT;
    791     m_sVenc_cfg.fps_num = 30;
    792     m_sVenc_cfg.fps_den = 1;
    793     m_sVenc_cfg.targetbitrate = 64000;
    794     m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12;
    795     m_codec = codec;
    796 
    797     if (codec == OMX_VIDEO_CodingMPEG4) {
    798         m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4;
    799         codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
    800         profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
    801         session_qp_range.minqp = 1;
    802         session_qp_range.maxqp = 31;
    803     } else if (codec == OMX_VIDEO_CodingH263) {
    804         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263;
    805         codec_profile.profile = VEN_PROFILE_H263_BASELINE;
    806         profile_level.level = VEN_LEVEL_H263_20;
    807         session_qp_range.minqp = 1;
    808         session_qp_range.maxqp = 31;
    809     } else if (codec == OMX_VIDEO_CodingAVC) {
    810         m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264;
    811         codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
    812         profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
    813         session_qp_range.minqp = 1;
    814         session_qp_range.maxqp = 51;
    815     } else if (codec == OMX_VIDEO_CodingVP8) {
    816         m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
    817         codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
    818         profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
    819         session_qp_range.minqp = 1;
    820         session_qp_range.maxqp = 128;
    821     }
    822     session_qp_values.minqp = session_qp_range.minqp;
    823     session_qp_values.maxqp = session_qp_range.maxqp;
    824 
    825     int ret;
    826     ret = subscribe_to_events(m_nDriver_fd);
    827 
    828     if (ret) {
    829         DEBUG_PRINT_ERROR("Subscribe Event Failed");
    830         return false;
    831     }
    832 
    833     struct v4l2_capability cap;
    834 
    835     struct v4l2_fmtdesc fdesc;
    836 
    837     struct v4l2_format fmt;
    838 
    839     struct v4l2_requestbuffers bufreq;
    840 
    841     ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
    842 
    843     if (ret) {
    844         DEBUG_PRINT_ERROR("Failed to query capabilities");
    845     } else {
    846         DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
    847                 " version = %d, capabilities = %x", cap.driver, cap.card,
    848                 cap.bus_info, cap.version, cap.capabilities);
    849     }
    850 
    851     ret=0;
    852     fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    853     fdesc.index=0;
    854 
    855     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
    856         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
    857                 fdesc.pixelformat, fdesc.flags);
    858         fdesc.index++;
    859     }
    860 
    861     fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    862     fdesc.index=0;
    863 
    864     while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
    865         DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
    866                 fdesc.pixelformat, fdesc.flags);
    867         fdesc.index++;
    868     }
    869 
    870     if (venc_handle->is_secure_session()) {
    871         m_sOutput_buff_property.alignment = SZ_1M;
    872         m_sInput_buff_property.alignment  = SZ_1M;
    873     } else {
    874         m_sOutput_buff_property.alignment = SZ_4K;
    875         m_sInput_buff_property.alignment  = SZ_4K;
    876     }
    877     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    878     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
    879     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
    880     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
    881 
    882     /*TODO: Return values not handled properly in this function anywhere.
    883      * Need to handle those.*/
    884     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
    885 
    886     if (ret) {
    887         DEBUG_PRINT_ERROR("Failed to set format on capture port");
    888         return false;
    889     }
    890 
    891     m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
    892 
    893     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    894     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
    895     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
    896     fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
    897 
    898     ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
    899     m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
    900 
    901     bufreq.memory = V4L2_MEMORY_USERPTR;
    902     bufreq.count = 2;
    903 
    904     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    905     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
    906     m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
    907 
    908     bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    909     bufreq.count = 2;
    910     ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
    911     m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
    912 
    913     if(venc_handle->is_secure_session()) {
    914         control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
    915         control.value = 1;
    916         DEBUG_PRINT_HIGH("ioctl: open secure device");
    917         ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
    918         if (ret) {
    919             DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
    920             return false;
    921         }
    922     }
    923 
    924     resume_in_stopped = 0;
    925     metadatamode = 0;
    926 
    927     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
    928     control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
    929 
    930     DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value);
    931 
    932     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
    933         DEBUG_PRINT_ERROR("Failed to set control");
    934 
    935     struct v4l2_frmsizeenum frmsize;
    936 
    937     //Get the hardware capabilities
    938     memset((void *)&frmsize,0,sizeof(frmsize));
    939     frmsize.index = 0;
    940     frmsize.pixel_format = m_sVenc_cfg.codectype;
    941     ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
    942 
    943     if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
    944         DEBUG_PRINT_ERROR("Failed to get framesizes");
    945         return false;
    946     }
    947 
    948     if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
    949         capability.min_width = frmsize.stepwise.min_width;
    950         capability.max_width = frmsize.stepwise.max_width;
    951         capability.min_height = frmsize.stepwise.min_height;
    952         capability.max_height = frmsize.stepwise.max_height;
    953     }
    954     //Initialize non-default parameters
    955     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
    956         control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
    957         control.value = 0x7fffffff;
    958         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
    959             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
    960     }
    961 
    962     return true;
    963 }
    964 
    965 
    966 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    967 {
    968     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    969     struct v4l2_event_subscription sub;
    970     int array_sz = sizeof(event_type)/sizeof(int);
    971     int i,rc;
    972 
    973     if (fd < 0) {
    974        DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    975         return OMX_ErrorBadParameter;
    976     }
    977 
    978     for (i = 0; i < array_sz; ++i) {
    979         memset(&sub, 0, sizeof(sub));
    980         sub.type = event_type[i];
    981         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    982 
    983         if (rc) {
    984            DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    985             break;
    986         }
    987     }
    988 
    989     return eRet;
    990 }
    991 
    992 void venc_dev::venc_close()
    993 {
    994     struct v4l2_encoder_cmd enc;
    995     DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
    996 
    997     if ((int)m_nDriver_fd >= 0) {
    998         enc.cmd = V4L2_ENC_CMD_STOP;
    999         ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc);
   1000         DEBUG_PRINT_HIGH("venc_close E");
   1001 
   1002         if (async_thread_created)
   1003             pthread_join(m_tid,NULL);
   1004 
   1005         DEBUG_PRINT_HIGH("venc_close X");
   1006         unsubscribe_to_events(m_nDriver_fd);
   1007         close(m_nDriver_fd);
   1008         m_nDriver_fd = -1;
   1009     }
   1010 
   1011     if (m_debug.infile) {
   1012         fclose(m_debug.infile);
   1013         m_debug.infile = NULL;
   1014     }
   1015 
   1016     if (m_debug.outfile) {
   1017         fclose(m_debug.outfile);
   1018         m_debug.outfile = NULL;
   1019     }
   1020 
   1021     if (m_debug.extradatafile) {
   1022         fclose(m_debug.extradatafile);
   1023         m_debug.extradatafile = NULL;
   1024     }
   1025 }
   1026 
   1027 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
   1028         OMX_U32 *actual_buff_count,
   1029         OMX_U32 *buff_size,
   1030         OMX_U32 port)
   1031 {
   1032     (void)min_buff_count, (void)buff_size;
   1033     unsigned long temp_count = 0;
   1034 
   1035     if (port == 0) {
   1036         if (*actual_buff_count > m_sInput_buff_property.mincount) {
   1037             temp_count = m_sInput_buff_property.actualcount;
   1038             m_sInput_buff_property.actualcount = *actual_buff_count;
   1039             DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count);
   1040         }
   1041     } else {
   1042         if (*actual_buff_count > m_sOutput_buff_property.mincount) {
   1043             temp_count = m_sOutput_buff_property.actualcount;
   1044             m_sOutput_buff_property.actualcount = *actual_buff_count;
   1045             DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count);
   1046         }
   1047     }
   1048 
   1049     return true;
   1050 
   1051 }
   1052 
   1053 bool venc_dev::venc_loaded_start()
   1054 {
   1055     return true;
   1056 }
   1057 
   1058 bool venc_dev::venc_loaded_stop()
   1059 {
   1060     return true;
   1061 }
   1062 
   1063 bool venc_dev::venc_loaded_start_done()
   1064 {
   1065     return true;
   1066 }
   1067 
   1068 bool venc_dev::venc_loaded_stop_done()
   1069 {
   1070     return true;
   1071 }
   1072 
   1073 bool venc_dev::venc_get_seq_hdr(void *buffer,
   1074         unsigned buffer_size, OMX_U32 *header_len)
   1075 {
   1076     (void) buffer, (void) buffer_size, (void) header_len;
   1077     return true;
   1078 }
   1079 
   1080 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
   1081         OMX_U32 *actual_buff_count,
   1082         OMX_U32 *buff_size,
   1083         OMX_U32 port)
   1084 {
   1085     struct v4l2_format fmt;
   1086     struct v4l2_requestbuffers bufreq;
   1087     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
   1088     int ret;
   1089 
   1090     if (port == 0) {
   1091         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1092         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   1093         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   1094         fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
   1095         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
   1096         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1097         bufreq.memory = V4L2_MEMORY_USERPTR;
   1098 
   1099         if (*actual_buff_count)
   1100             bufreq.count = *actual_buff_count;
   1101         else
   1102             bufreq.count = 2;
   1103 
   1104         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1105         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
   1106 
   1107         if (ret) {
   1108             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
   1109             return false;
   1110         }
   1111 
   1112         m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
   1113         *min_buff_count = m_sInput_buff_property.mincount;
   1114         *actual_buff_count = m_sInput_buff_property.actualcount;
   1115 #ifdef USE_ION
   1116         // For ION memory allocations of the allocated buffer size
   1117         // must be 4k aligned, hence aligning the input buffer
   1118         // size to 4k.
   1119         m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
   1120 #endif
   1121         *buff_size = m_sInput_buff_property.datasize;
   1122     } else {
   1123         int extra_idx = 0;
   1124         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1125         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1126         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1127         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1128 
   1129         ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt);
   1130         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1131         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1132         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1133         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1134         fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1135 
   1136         ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
   1137         m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1138         bufreq.memory = V4L2_MEMORY_USERPTR;
   1139 
   1140         if (*actual_buff_count)
   1141             bufreq.count = *actual_buff_count;
   1142         else
   1143             bufreq.count = 2;
   1144 
   1145         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1146         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
   1147 
   1148         if (ret) {
   1149             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
   1150             return false;
   1151         }
   1152 
   1153         m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
   1154         *min_buff_count = m_sOutput_buff_property.mincount;
   1155         *actual_buff_count = m_sOutput_buff_property.actualcount;
   1156         *buff_size = m_sOutput_buff_property.datasize;
   1157         num_planes = fmt.fmt.pix_mp.num_planes;
   1158         extra_idx = EXTRADATA_IDX(num_planes);
   1159 
   1160         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   1161             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   1162         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   1163             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   1164             return OMX_ErrorBadParameter;
   1165         }
   1166 
   1167         extradata_info.buffer_size = extra_data_size;
   1168         extradata_info.count = m_sOutput_buff_property.actualcount;
   1169         extradata_info.size = extradata_info.buffer_size * extradata_info.count;
   1170     }
   1171 
   1172     return true;
   1173 }
   1174 
   1175 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
   1176 {
   1177     DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
   1178     struct v4l2_format fmt;
   1179     struct v4l2_requestbuffers bufreq;
   1180     int ret;
   1181 
   1182     switch ((int)index) {
   1183         case OMX_IndexParamPortDefinition:
   1184             {
   1185                 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   1186                 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   1187                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition");
   1188 
   1189                 if (portDefn->nPortIndex == PORT_INDEX_IN) {
   1190                     if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) {
   1191                         return false;
   1192                     }
   1193 
   1194                     if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
   1195                         return false;
   1196                     }
   1197                     if ((display_info.w * display_info.h) > (OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
   1198                         && enable_mv_narrow_searchrange &&
   1199                         (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
   1200                         (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
   1201                         if (venc_set_searchrange() == false) {
   1202                             DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
   1203                         }
   1204                     }
   1205                     if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
   1206                             m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
   1207                         DEBUG_PRINT_LOW("Basic parameter has changed");
   1208                         m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight;
   1209                         m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth;
   1210                         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1211                         fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   1212                         fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   1213                         fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
   1214 
   1215                         if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   1216                             DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
   1217                             return false;
   1218                         }
   1219 
   1220                         m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1221                         bufreq.memory = V4L2_MEMORY_USERPTR;
   1222                         bufreq.count = portDefn->nBufferCountActual;
   1223                         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1224 
   1225                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   1226                             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
   1227                             return false;
   1228                         }
   1229 
   1230                         if (bufreq.count == portDefn->nBufferCountActual)
   1231                             m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count;
   1232 
   1233                         if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount)
   1234                             m_sInput_buff_property.actualcount = portDefn->nBufferCountActual;
   1235                     }
   1236 
   1237                     DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
   1238                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
   1239                 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
   1240                     m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
   1241                     m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
   1242                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1243                     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   1244                     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   1245                     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   1246 
   1247                     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   1248                         DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
   1249                         return false;
   1250                     }
   1251 
   1252                     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   1253 
   1254                     if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) {
   1255                         return false;
   1256                     }
   1257 
   1258                         m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
   1259                         bufreq.memory = V4L2_MEMORY_USERPTR;
   1260                         bufreq.count = portDefn->nBufferCountActual;
   1261                         bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1262 
   1263                         if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   1264                             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
   1265                                     (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount);
   1266                             return false;
   1267                         }
   1268 
   1269                         if (bufreq.count == portDefn->nBufferCountActual)
   1270                             m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count;
   1271 
   1272                         if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount)
   1273                             m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual;
   1274 
   1275                         if (num_planes > 1)
   1276                             extradata_info.count = m_sOutput_buff_property.actualcount;
   1277 
   1278                     DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
   1279                             (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
   1280                 } else {
   1281                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition");
   1282                 }
   1283 
   1284                 break;
   1285             }
   1286         case OMX_IndexParamVideoPortFormat:
   1287             {
   1288                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt;
   1289                 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   1290                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat");
   1291 
   1292                 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
   1293                     if (!venc_set_color_format(portFmt->eColorFormat)) {
   1294                         return false;
   1295                     }
   1296                 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1297                     if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) {
   1298                         return false;
   1299                     }
   1300                 } else {
   1301                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
   1302                 }
   1303 
   1304                 break;
   1305             }
   1306         case OMX_IndexParamVideoBitrate:
   1307             {
   1308                 OMX_VIDEO_PARAM_BITRATETYPE* pParam;
   1309                 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
   1310                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
   1311 
   1312                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1313                     if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
   1314                         DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
   1315                         return false;
   1316                     }
   1317 
   1318                     if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
   1319                         DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
   1320                         return false;
   1321                     }
   1322                 } else {
   1323                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate");
   1324                 }
   1325 
   1326                 break;
   1327             }
   1328         case OMX_IndexParamVideoMpeg4:
   1329             {
   1330                 OMX_VIDEO_PARAM_MPEG4TYPE* pParam;
   1331                 OMX_U32 bFrames = 0;
   1332 
   1333                 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
   1334                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4");
   1335 
   1336                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1337                     if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
   1338                         DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
   1339                         return false;
   1340                     }
   1341 
   1342                     m_profile_set = false;
   1343                     m_level_set = false;
   1344 
   1345                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1346                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
   1347                         return false;
   1348                     } else {
   1349                         if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
   1350                             if (pParam->nBFrames) {
   1351                                 bFrames = pParam->nBFrames;
   1352                             }
   1353                         } else {
   1354                             if (pParam->nBFrames) {
   1355                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
   1356                                 bFrames = 0;
   1357                             }
   1358                         }
   1359                     }
   1360 
   1361                     if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
   1362                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1363                         return false;
   1364                     }
   1365 
   1366                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
   1367                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
   1368                         return false;
   1369                     }
   1370                 } else {
   1371                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4");
   1372                 }
   1373 
   1374                 break;
   1375             }
   1376         case OMX_IndexParamVideoH263:
   1377             {
   1378                 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
   1379                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263");
   1380                 OMX_U32 bFrames = 0;
   1381 
   1382                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1383                     m_profile_set = false;
   1384                     m_level_set = false;
   1385 
   1386                     if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1387                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
   1388                         return false;
   1389                     }
   1390 
   1391                     if (pParam->nBFrames)
   1392                         DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
   1393 
   1394                     if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
   1395                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1396                         return false;
   1397                     }
   1398                 } else {
   1399                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
   1400                 }
   1401 
   1402                 break;
   1403             }
   1404         case OMX_IndexParamVideoAvc:
   1405             {
   1406                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
   1407                 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
   1408                 OMX_U32 bFrames = 0;
   1409 
   1410                 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1411                     DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d",
   1412                             pParam->eProfile,pParam->eLevel);
   1413 
   1414                     m_profile_set = false;
   1415                     m_level_set = false;
   1416 
   1417                     if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
   1418                         DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
   1419                                 pParam->eProfile, pParam->eLevel);
   1420                         return false;
   1421                     } else {
   1422                         if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
   1423                             (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
   1424                             if (pParam->nBFrames) {
   1425                                 bFrames = pParam->nBFrames;
   1426                             }
   1427                         } else {
   1428                             if (pParam->nBFrames) {
   1429                                 DEBUG_PRINT_ERROR("Warning: B frames not supported");
   1430                                 bFrames = 0;
   1431                             }
   1432                         }
   1433                     }
   1434 
   1435                     if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
   1436                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1437                         return false;
   1438                     }
   1439 
   1440                     if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
   1441                         DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
   1442                         return false;
   1443                     }
   1444 
   1445                     if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
   1446                         DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
   1447                         return false;
   1448                     }
   1449 
   1450                     if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
   1451                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
   1452                         return false;
   1453                     }
   1454                 } else {
   1455                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
   1456                 }
   1457 
   1458                 //TBD, lot of other variables to be updated, yet to decide
   1459                 break;
   1460             }
   1461         case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
   1462             {
   1463                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
   1464                 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
   1465                 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
   1466                     DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
   1467                                         pParam->eProfile, pParam->eLevel);
   1468                     return false;
   1469                 }
   1470 
   1471                 if(!venc_set_ltrmode(1, 1)) {
   1472                    DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
   1473                    return false;
   1474                 }
   1475 
   1476                  // For VP8, hier-p and ltr are mutually exclusive features in firmware
   1477                  // Disable hier-p if ltr is enabled.
   1478                  if (m_codec == OMX_VIDEO_CodingVP8) {
   1479                      DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
   1480                      if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
   1481                         DEBUG_PRINT_ERROR("Disabling Hier P count failed");
   1482                      }
   1483                  }
   1484 
   1485                 break;
   1486             }
   1487         case OMX_IndexParamVideoIntraRefresh:
   1488             {
   1489                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
   1490                 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh =
   1491                     (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData;
   1492 
   1493                 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1494                     if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) {
   1495                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
   1496                         return false;
   1497                     }
   1498                 } else {
   1499                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
   1500                 }
   1501 
   1502                 break;
   1503             }
   1504         case OMX_IndexParamVideoErrorCorrection:
   1505             {
   1506                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
   1507                 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience =
   1508                     (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData;
   1509 
   1510                 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1511                     if (venc_set_error_resilience(error_resilience) == false) {
   1512                         DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
   1513                         return false;
   1514                     }
   1515                 } else {
   1516                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
   1517                 }
   1518 
   1519                 break;
   1520             }
   1521         case OMX_IndexParamVideoProfileLevelCurrent:
   1522             {
   1523                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
   1524                 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level =
   1525                     (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   1526 
   1527                 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1528                     m_profile_set = false;
   1529                     m_level_set = false;
   1530 
   1531                     if (!venc_set_profile_level (profile_level->eProfile,
   1532                                 profile_level->eLevel)) {
   1533                         DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
   1534                         return false;
   1535                     }
   1536                 } else {
   1537                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
   1538                 }
   1539 
   1540                 break;
   1541             }
   1542         case OMX_IndexParamVideoQuantization:
   1543             {
   1544                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
   1545                 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp =
   1546                     (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData;
   1547                 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1548                     if (venc_set_session_qp (session_qp->nQpI,
   1549                                 session_qp->nQpP,
   1550                                 session_qp->nQpB) == false) {
   1551                         DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed");
   1552                         return false;
   1553                     }
   1554                 } else {
   1555                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
   1556                 }
   1557 
   1558                 break;
   1559             }
   1560         case QOMX_IndexParamVideoInitialQp:
   1561             {
   1562                 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
   1563                     (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
   1564                  if (initqp->bEnableInitQp) {
   1565                     DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
   1566                     if(venc_enable_initial_qp(initqp) == false) {
   1567                        DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
   1568                        return OMX_ErrorUnsupportedSetting;
   1569                      }
   1570                  } else
   1571                     DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
   1572                 break;
   1573             }
   1574         case OMX_QcomIndexParamVideoQPRange:
   1575             {
   1576                 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
   1577                 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
   1578                     (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
   1579 
   1580                 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   1581                     if(venc_set_session_qp_range (session_qp_range->minQP,
   1582                                 session_qp_range->maxQP) == false) {
   1583                         DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
   1584                             (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
   1585                         return false;
   1586                     } else {
   1587                         session_qp_values.minqp = session_qp_range->minQP;
   1588                         session_qp_values.maxqp = session_qp_range->maxQP;
   1589                     }
   1590                 } else {
   1591                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
   1592                 }
   1593 
   1594                 break;
   1595             }
   1596         case OMX_QcomIndexEnableSliceDeliveryMode:
   1597             {
   1598                 QOMX_EXTNINDEX_PARAMTYPE* pParam =
   1599                     (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
   1600 
   1601                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
   1602                     if (venc_set_slice_delivery_mode(pParam->bEnable) == false) {
   1603                         DEBUG_PRINT_ERROR("Setting slice delivery mode failed");
   1604                         return OMX_ErrorUnsupportedSetting;
   1605                     }
   1606                 } else {
   1607                     DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode "
   1608                             "called on wrong port(%u)", (unsigned int)pParam->nPortIndex);
   1609                     return OMX_ErrorBadPortIndex;
   1610                 }
   1611 
   1612                 break;
   1613             }
   1614         case OMX_ExtraDataVideoEncoderSliceInfo:
   1615             {
   1616                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
   1617                 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
   1618 
   1619                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
   1620                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
   1621                     return false;
   1622                 }
   1623 
   1624                 extradata = true;
   1625                 break;
   1626             }
   1627         case OMX_ExtraDataVideoEncoderMBInfo:
   1628             {
   1629                 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
   1630                 OMX_BOOL extra_data =  *(OMX_BOOL *)(paramData);
   1631 
   1632                 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
   1633                     DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
   1634                     return false;
   1635                 }
   1636 
   1637                 extradata = true;
   1638                 break;
   1639             }
   1640         case OMX_QcomIndexParamSequenceHeaderWithIDR:
   1641             {
   1642                 PrependSPSPPSToIDRFramesParams * pParam =
   1643                     (PrependSPSPPSToIDRFramesParams *)paramData;
   1644 
   1645                 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
   1646                 if(venc_set_inband_video_header(pParam->bEnable) == false) {
   1647                     DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
   1648                     return OMX_ErrorUnsupportedSetting;
   1649                 }
   1650 
   1651                 break;
   1652             }
   1653         case OMX_QcomIndexParamH264AUDelimiter:
   1654             {
   1655                 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
   1656                     (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
   1657 
   1658                 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
   1659                 if(venc_set_au_delimiter(pParam->bEnable) == false) {
   1660                     DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
   1661                     return OMX_ErrorUnsupportedSetting;
   1662                 }
   1663 
   1664                 break;
   1665             }
   1666          case OMX_QcomIndexHierarchicalStructure:
   1667            {
   1668                QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
   1669                    (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
   1670 
   1671                 if (pParam->nPortIndex == PORT_INDEX_OUT) {
   1672                     if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
   1673                         DEBUG_PRINT_ERROR("Setting Hier P count failed");
   1674                         return false;
   1675                     }
   1676                 } else {
   1677                     DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
   1678                     return false;
   1679                 }
   1680 
   1681                 // For VP8, hier-p and ltr are mutually exclusive features in firmware
   1682                 // Disable ltr if hier-p is enabled.
   1683                 if (m_codec == OMX_VIDEO_CodingVP8) {
   1684                     DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
   1685                     if(!venc_set_ltrmode(0, 1)) {
   1686                          DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
   1687                      }
   1688                 }
   1689                 break;
   1690            }
   1691         case OMX_QcomIndexParamPerfLevel:
   1692             {
   1693                 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
   1694                         (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
   1695                 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
   1696                 if(!venc_set_perf_level(pParam->ePerfLevel)) {
   1697                     DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
   1698                     return false;
   1699                 } else {
   1700                     performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
   1701                 }
   1702                 break;
   1703             }
   1704         case OMX_QcomIndexParamH264VUITimingInfo:
   1705             {
   1706                 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
   1707                         (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
   1708                 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
   1709                 if(venc_set_vui_timing_info(pParam->bEnable) == false) {
   1710                     DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
   1711                     return false;
   1712                 } else {
   1713                     vui_timing_info.enabled = (unsigned int) pParam->bEnable;
   1714                 }
   1715                 break;
   1716             }
   1717         case OMX_QcomIndexParamPeakBitrate:
   1718             {
   1719                 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
   1720                         (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
   1721                 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
   1722                 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
   1723                     DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
   1724                     return false;
   1725                 } else {
   1726                     peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
   1727                 }
   1728                 break;
   1729             }
   1730        case OMX_QcomIndexParamSetMVSearchrange:
   1731             {
   1732                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
   1733                is_searchrange_set = true;
   1734                if (!venc_set_searchrange()) {
   1735                    DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
   1736                    return false;
   1737                }
   1738             }
   1739             break;
   1740         case OMX_IndexParamVideoSliceFMO:
   1741         default:
   1742             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
   1743                     index);
   1744             break;
   1745             //case
   1746     }
   1747 
   1748     return true;
   1749 }
   1750 
   1751 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
   1752 {
   1753 
   1754     DEBUG_PRINT_LOW("Inside venc_set_config");
   1755 
   1756     switch ((int)index) {
   1757         case OMX_IndexConfigVideoBitrate:
   1758             {
   1759                 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
   1760                     configData;
   1761                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate");
   1762 
   1763                 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   1764                     if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) {
   1765                         DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed");
   1766                         return false;
   1767                     }
   1768                 } else {
   1769                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
   1770                 }
   1771 
   1772                 break;
   1773             }
   1774         case OMX_IndexConfigVideoFramerate:
   1775             {
   1776                 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
   1777                     configData;
   1778                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate");
   1779 
   1780                 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   1781                     if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) {
   1782                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
   1783                         return false;
   1784                     }
   1785                 } else {
   1786                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
   1787                 }
   1788 
   1789                 break;
   1790             }
   1791         case QOMX_IndexConfigVideoIntraperiod:
   1792             {
   1793                 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
   1794                 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod =
   1795                     (QOMX_VIDEO_INTRAPERIODTYPE *)configData;
   1796 
   1797                 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
   1798                     if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) {
   1799                         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   1800                         return false;
   1801                     }
   1802                 }
   1803 
   1804                 break;
   1805             }
   1806         case OMX_IndexConfigVideoIntraVOPRefresh:
   1807             {
   1808                 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)
   1809                     configData;
   1810                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh");
   1811 
   1812                 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   1813                     if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) {
   1814                         DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed");
   1815                         return false;
   1816                     }
   1817                 } else {
   1818                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
   1819                 }
   1820 
   1821                 break;
   1822             }
   1823         case OMX_IndexConfigCommonRotate:
   1824             {
   1825                 OMX_CONFIG_ROTATIONTYPE *config_rotation =
   1826                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
   1827                 OMX_U32 nFrameWidth;
   1828                 if (true == deinterlace_enabled) {
   1829                     DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
   1830                     return false;
   1831                 }
   1832                 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
   1833                 nFrameWidth = m_sVenc_cfg.dvs_width;
   1834                 m_sVenc_cfg.dvs_width  = m_sVenc_cfg.dvs_height;
   1835                 m_sVenc_cfg.dvs_height = nFrameWidth;
   1836 
   1837                 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
   1838                     DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed");
   1839                     return false;
   1840                 }
   1841 
   1842                 break;
   1843             }
   1844         case OMX_IndexConfigVideoAVCIntraPeriod:
   1845             {
   1846                 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData;
   1847                 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod");
   1848 
   1849                 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod)
   1850                         == false) {
   1851                     DEBUG_PRINT_ERROR("ERROR: Setting "
   1852                             "OMX_IndexConfigVideoAVCIntraPeriod failed");
   1853                     return false;
   1854                 }
   1855                 break;
   1856             }
   1857         case OMX_IndexConfigCommonDeinterlace:
   1858             {
   1859                 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
   1860                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
   1861                 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
   1862                     if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
   1863                         m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
   1864                     {
   1865                         DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
   1866                         return false;
   1867                     }
   1868                     if(venc_set_deinterlace(deinterlace->nEnable) == false) {
   1869                         DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
   1870                         return false;
   1871                     }
   1872                 } else {
   1873                 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
   1874                 }
   1875                 break;
   1876             }
   1877        case OMX_IndexConfigVideoVp8ReferenceFrame:
   1878            {
   1879                OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
   1880                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
   1881                 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
   1882                     (vp8refframe->bUseGoldenFrame)) {
   1883                     if(venc_set_useltr() == false) {
   1884                         DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
   1885                         return false;
   1886                     }
   1887                 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
   1888                     (vp8refframe->bGoldenFrameRefresh)) {
   1889                     if(venc_set_markltr() == false) {
   1890                         DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
   1891                         return false;
   1892                     }
   1893                 } else {
   1894                     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
   1895                 }
   1896                 break;
   1897             }
   1898         default:
   1899             DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
   1900             break;
   1901     }
   1902 
   1903     return true;
   1904 }
   1905 
   1906 unsigned venc_dev::venc_stop( void)
   1907 {
   1908     struct venc_msg venc_msg;
   1909     struct v4l2_requestbuffers bufreq;
   1910     int rc = 0, ret = 0;
   1911 
   1912     if (!stopped) {
   1913         enum v4l2_buf_type cap_type;
   1914 
   1915         if (streaming[OUTPUT_PORT]) {
   1916             cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1917             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
   1918 
   1919             if (rc) {
   1920                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
   1921                         cap_type, rc);
   1922             } else
   1923                 streaming[OUTPUT_PORT] = false;
   1924 
   1925             DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
   1926             bufreq.memory = V4L2_MEMORY_USERPTR;
   1927             bufreq.count = 0;
   1928             bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1929             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
   1930 
   1931             if (ret) {
   1932                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
   1933                 return false;
   1934             }
   1935         }
   1936 
   1937         if (!rc && streaming[CAPTURE_PORT]) {
   1938             cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1939             rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type);
   1940 
   1941             if (rc) {
   1942                 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d",
   1943                         cap_type, rc);
   1944             } else
   1945                 streaming[CAPTURE_PORT] = false;
   1946 
   1947             DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
   1948             bufreq.memory = V4L2_MEMORY_USERPTR;
   1949             bufreq.count = 0;
   1950             bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1951             ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
   1952 
   1953             if (ret) {
   1954                 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
   1955                 return false;
   1956             }
   1957         }
   1958 
   1959         if (!rc && !ret) {
   1960             venc_stop_done();
   1961             stopped = 1;
   1962             /*set flag to re-configure when started again*/
   1963             resume_in_stopped = 1;
   1964 
   1965         }
   1966     }
   1967 
   1968     return rc;
   1969 }
   1970 
   1971 unsigned venc_dev::venc_pause(void)
   1972 {
   1973     pthread_mutex_lock(&pause_resume_mlock);
   1974     paused = true;
   1975     pthread_mutex_unlock(&pause_resume_mlock);
   1976     return 0;
   1977 }
   1978 
   1979 unsigned venc_dev::venc_resume(void)
   1980 {
   1981     pthread_mutex_lock(&pause_resume_mlock);
   1982     paused = false;
   1983     pthread_mutex_unlock(&pause_resume_mlock);
   1984 
   1985     return pthread_cond_signal(&pause_resume_cond);
   1986 }
   1987 
   1988 unsigned venc_dev::venc_start_done(void)
   1989 {
   1990     struct venc_msg venc_msg;
   1991     venc_msg.msgcode = VEN_MSG_START;
   1992     venc_msg.statuscode = VEN_S_SUCCESS;
   1993     venc_handle->async_message_process(venc_handle,&venc_msg);
   1994     return 0;
   1995 }
   1996 
   1997 unsigned venc_dev::venc_stop_done(void)
   1998 {
   1999     struct venc_msg venc_msg;
   2000     free_extradata();
   2001     venc_msg.msgcode=VEN_MSG_STOP;
   2002     venc_msg.statuscode=VEN_S_SUCCESS;
   2003     venc_handle->async_message_process(venc_handle,&venc_msg);
   2004     return 0;
   2005 }
   2006 
   2007 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid)
   2008 {
   2009     async_thread_created = true;
   2010     m_tid=tid;
   2011     return 0;
   2012 }
   2013 
   2014 
   2015 unsigned venc_dev::venc_start(void)
   2016 {
   2017     enum v4l2_buf_type buf_type;
   2018     int ret, r;
   2019     struct v4l2_control control;
   2020 
   2021     memset(&control, 0, sizeof(control));
   2022 
   2023     DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
   2024             __func__);
   2025 
   2026     if (!venc_set_profile_level(0, 0)) {
   2027         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
   2028                 __func__);
   2029     } else {
   2030         DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
   2031                 __func__, codec_profile.profile, profile_level.level);
   2032     }
   2033 
   2034     venc_config_print();
   2035 
   2036     if(resume_in_stopped){
   2037         /*set buffercount when restarted*/
   2038         venc_reconfig_reqbufs();
   2039         resume_in_stopped = 0;
   2040     }
   2041 
   2042     /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */
   2043     if (slice_mode.enable && multislice.mslice_size &&
   2044             (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
   2045         DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
   2046                 (m_sVenc_cfg.dvs_width *  m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size),
   2047                 MAX_SUPPORTED_SLICES_PER_FRAME);
   2048         return 1;
   2049     }
   2050 
   2051     buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2052     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2053     ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
   2054 
   2055     if (ret)
   2056         return 1;
   2057 
   2058     streaming[CAPTURE_PORT] = true;
   2059 
   2060     control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
   2061     control.value = 1;
   2062     ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2063     if (ret) {
   2064         DEBUG_PRINT_ERROR("failed to request seq header");
   2065         return 1;
   2066     }
   2067 
   2068     stopped = 0;
   2069     return 0;
   2070 }
   2071 
   2072 void venc_dev::venc_config_print()
   2073 {
   2074 
   2075     DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %ld, Profile %ld, level : %ld",
   2076             m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
   2077 
   2078     DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld",
   2079             m_sVenc_cfg.input_width, m_sVenc_cfg.input_height,
   2080             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
   2081 
   2082     DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
   2083             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
   2084             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
   2085 
   2086     DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld",
   2087             bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
   2088 
   2089     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
   2090             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
   2091 
   2092     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
   2093             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
   2094 
   2095     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
   2096             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
   2097 
   2098     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
   2099             session_qp_values.minqp, session_qp_values.maxqp);
   2100 
   2101     DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
   2102             voptimecfg.voptime_resolution, multislice.mslice_mode,
   2103             multislice.mslice_size);
   2104 
   2105     DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
   2106             entropy.longentropysel, entropy.cabacmodel);
   2107 
   2108     DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
   2109             dbkfilter.db_mode, dbkfilter.slicealpha_offset,
   2110             dbkfilter.slicebeta_offset);
   2111 
   2112     DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
   2113             intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
   2114 
   2115     DEBUG_PRINT_HIGH("ENC_CONFIG: Hier-P layers: %d", hier_p_layers.numlayers);
   2116 
   2117     DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
   2118 
   2119     DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
   2120 
   2121     DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
   2122 }
   2123 
   2124 bool venc_dev::venc_reconfig_reqbufs()
   2125 {
   2126     struct v4l2_requestbuffers bufreq;
   2127 
   2128     bufreq.memory = V4L2_MEMORY_USERPTR;
   2129     bufreq.count = m_sInput_buff_property.actualcount;
   2130     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2131     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   2132             DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
   2133             return false;
   2134     }
   2135 
   2136     bufreq.memory = V4L2_MEMORY_USERPTR;
   2137     bufreq.count = m_sOutput_buff_property.actualcount;
   2138     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2139     if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
   2140     {
   2141             DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
   2142             return false;
   2143     }
   2144     return true;
   2145 }
   2146 
   2147 unsigned venc_dev::venc_flush( unsigned port)
   2148 {
   2149     struct v4l2_encoder_cmd enc;
   2150     DEBUG_PRINT_LOW("in %s", __func__);
   2151 
   2152     enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH;
   2153     enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE;
   2154 
   2155     if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) {
   2156         DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port);
   2157         return -1;
   2158     }
   2159 
   2160     return 0;
   2161 
   2162 }
   2163 
   2164 //allocating I/P memory from pmem and register with the device
   2165 
   2166 
   2167 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index)
   2168 {
   2169 
   2170     struct pmem *pmem_tmp;
   2171     struct v4l2_buffer buf;
   2172     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   2173     int rc = 0, extra_idx;
   2174 
   2175     pmem_tmp = (struct pmem *)buf_addr;
   2176     DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
   2177 
   2178     if (port == PORT_INDEX_IN) {
   2179         buf.index = index;
   2180         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2181         buf.memory = V4L2_MEMORY_USERPTR;
   2182         plane[0].length = pmem_tmp->size;
   2183         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
   2184         plane[0].reserved[0] = pmem_tmp->fd;
   2185         plane[0].reserved[1] = 0;
   2186         plane[0].data_offset = pmem_tmp->offset;
   2187         buf.m.planes = plane;
   2188         buf.length = 1;
   2189 
   2190         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
   2191 
   2192         if (rc)
   2193             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
   2194     } else if (port == PORT_INDEX_OUT) {
   2195         extra_idx = EXTRADATA_IDX(num_planes);
   2196 
   2197         if ((num_planes > 1) && (extra_idx)) {
   2198             rc = allocate_extradata();
   2199 
   2200             if (rc)
   2201                 DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", rc);
   2202         }
   2203 
   2204         buf.index = index;
   2205         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2206         buf.memory = V4L2_MEMORY_USERPTR;
   2207         plane[0].length = pmem_tmp->size;
   2208         plane[0].m.userptr = (unsigned long)pmem_tmp->buffer;
   2209         plane[0].reserved[0] = pmem_tmp->fd;
   2210         plane[0].reserved[1] = 0;
   2211         plane[0].data_offset = pmem_tmp->offset;
   2212         buf.m.planes = plane;
   2213         buf.length = num_planes;
   2214 
   2215         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   2216             plane[extra_idx].length = extradata_info.buffer_size;
   2217             plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
   2218 #ifdef USE_ION
   2219             plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
   2220 #endif
   2221             plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
   2222             plane[extra_idx].data_offset = 0;
   2223         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   2224             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   2225             return OMX_ErrorBadParameter;
   2226         }
   2227 
   2228         rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
   2229 
   2230         if (rc)
   2231             DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
   2232     } else {
   2233         DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index ");
   2234         return false;
   2235     }
   2236 
   2237     return true;
   2238 }
   2239 
   2240 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port)
   2241 {
   2242     struct pmem *pmem_tmp;
   2243     struct venc_bufferpayload dev_buffer;
   2244 
   2245     memset(&dev_buffer, 0, sizeof(dev_buffer));
   2246     pmem_tmp = (struct pmem *)buf_addr;
   2247 
   2248     if (port == PORT_INDEX_IN) {
   2249         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   2250         dev_buffer.fd  = pmem_tmp->fd;
   2251         dev_buffer.maped_size = pmem_tmp->size;
   2252         dev_buffer.sz = pmem_tmp->size;
   2253         dev_buffer.offset = pmem_tmp->offset;
   2254         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
   2255                 dev_buffer.pbuffer, \
   2256                 dev_buffer.fd, \
   2257                 dev_buffer.offset, \
   2258                 dev_buffer.maped_size);
   2259 
   2260     } else if (port == PORT_INDEX_OUT) {
   2261         dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer;
   2262         dev_buffer.fd  = pmem_tmp->fd;
   2263         dev_buffer.sz = pmem_tmp->size;
   2264         dev_buffer.maped_size = pmem_tmp->size;
   2265         dev_buffer.offset = pmem_tmp->offset;
   2266 
   2267         DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
   2268                 dev_buffer.pbuffer, \
   2269                 dev_buffer.fd, \
   2270                 dev_buffer.offset, \
   2271                 dev_buffer.maped_size);
   2272     } else {
   2273         DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
   2274         return false;
   2275     }
   2276 
   2277     return true;
   2278 }
   2279 
   2280 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
   2281         OMX_U32 width, OMX_U32 height)
   2282 {
   2283     OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
   2284             y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
   2285             uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
   2286             uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
   2287             src_chroma_offset = width * height;
   2288 
   2289     if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
   2290         OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
   2291         //Do chroma first, so that we can convert it in-place
   2292         src_buf += width * height;
   2293         dst_buf += y_stride * y_scanlines;
   2294         for (int line = height / 2 - 1; line >= 0; --line) {
   2295             memmove(dst_buf + line * uv_stride,
   2296                     src_buf + line * width,
   2297                     width);
   2298         }
   2299 
   2300         dst_buf = src_buf = buffer->pBuffer;
   2301         //Copy the Y next
   2302         for (int line = height - 1; line > 0; --line) {
   2303             memmove(dst_buf + line * y_stride,
   2304                     src_buf + line * width,
   2305                     width);
   2306         }
   2307     } else {
   2308         DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
   2309                 Insufficient bufferLen=%u v/s Required=%u",
   2310                 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
   2311                 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
   2312         return false;
   2313     }
   2314 
   2315     return true;
   2316 }
   2317 
   2318 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
   2319 {
   2320     if (!perflevel) {
   2321         DEBUG_PRINT_ERROR("Null pointer error");
   2322         return false;
   2323     } else {
   2324         *perflevel = performance_level.perflevel;
   2325         return true;
   2326     }
   2327 }
   2328 
   2329 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
   2330 {
   2331     if (!enabled) {
   2332         DEBUG_PRINT_ERROR("Null pointer error");
   2333         return false;
   2334     } else {
   2335         *enabled = vui_timing_info.enabled;
   2336         return true;
   2337     }
   2338 }
   2339 
   2340 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
   2341 {
   2342     if (!peakbitrate) {
   2343         DEBUG_PRINT_ERROR("Null pointer error");
   2344         return false;
   2345     } else {
   2346         *peakbitrate = peak_bitrate.peakbitrate;
   2347         return true;
   2348     }
   2349 }
   2350 
   2351 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd)
   2352 {
   2353     struct pmem *temp_buffer;
   2354     struct v4l2_buffer buf;
   2355     struct v4l2_plane plane;
   2356     int rc=0;
   2357     struct OMX_BUFFERHEADERTYPE *bufhdr;
   2358     encoder_media_buffer_type * meta_buf = NULL;
   2359     temp_buffer = (struct pmem *)buffer;
   2360 
   2361     memset (&buf, 0, sizeof(buf));
   2362     memset (&plane, 0, sizeof(plane));
   2363 
   2364     if (buffer == NULL) {
   2365         DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL");
   2366         return false;
   2367     }
   2368 
   2369     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   2370 
   2371     DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen);
   2372 
   2373     if (pmem_data_buf) {
   2374         DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
   2375         plane.m.userptr = (unsigned long)pmem_data_buf;
   2376         plane.data_offset = bufhdr->nOffset;
   2377         plane.length = bufhdr->nAllocLen;
   2378         plane.bytesused = bufhdr->nFilledLen;
   2379     } else {
   2380         // --------------------------------------------------------------------------------------
   2381         // [Usage]             [metadatamode] [Type]        [color_format] [Where is buffer info]
   2382         // ---------------------------------------------------------------------------------------
   2383         // Camera-2              1            CameraSource   0              meta-handle
   2384         // Camera-3              1            GrallocSource  0              gralloc-private-handle
   2385         // surface encode (RBG)  1            GrallocSource  1              bufhdr (color-converted)
   2386         // CPU (Eg: MediaCodec)  0            --             0              bufhdr
   2387         // ---------------------------------------------------------------------------------------
   2388         if (metadatamode) {
   2389             plane.m.userptr = index;
   2390             meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer;
   2391 
   2392             if (!meta_buf) {
   2393                 //empty EOS buffer
   2394                 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
   2395                     plane.data_offset = bufhdr->nOffset;
   2396                     plane.length = bufhdr->nAllocLen;
   2397                     plane.bytesused = bufhdr->nFilledLen;
   2398                     DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
   2399                 } else {
   2400                     return false;
   2401                 }
   2402             } else if (!color_format) {
   2403                 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
   2404                     if (meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709)
   2405                         buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
   2406                     plane.data_offset = meta_buf->meta_handle->data[1];
   2407                     plane.length = meta_buf->meta_handle->data[2];
   2408                     plane.bytesused = meta_buf->meta_handle->data[2];
   2409                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x",
   2410                             fd, plane.bytesused, plane.length, buf.flags);
   2411                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
   2412                     private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
   2413                     fd = handle->fd;
   2414                     plane.data_offset = 0;
   2415                     plane.length = handle->size;
   2416                     plane.bytesused = handle->size;
   2417                         DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
   2418                                 ": filled %d of %d", fd, plane.bytesused, plane.length);
   2419                 }
   2420             } else {
   2421                 plane.data_offset = bufhdr->nOffset;
   2422                 plane.length = bufhdr->nAllocLen;
   2423                 plane.bytesused = bufhdr->nFilledLen;
   2424                 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d "
   2425                         ": filled %d of %d", fd, plane.bytesused, plane.length);
   2426             }
   2427         } else {
   2428             plane.data_offset = bufhdr->nOffset;
   2429             plane.length = bufhdr->nAllocLen;
   2430             plane.bytesused = bufhdr->nFilledLen;
   2431             DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
   2432                     fd, plane.bytesused, plane.length);
   2433         }
   2434     }
   2435 
   2436     buf.index = index;
   2437     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2438     buf.memory = V4L2_MEMORY_USERPTR;
   2439     plane.reserved[0] = fd;
   2440     plane.reserved[1] = 0;
   2441     buf.m.planes = &plane;
   2442     buf.length = 1;
   2443 
   2444     if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
   2445         buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
   2446 
   2447     buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
   2448     buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
   2449     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
   2450 
   2451     if (rc) {
   2452         DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver");
   2453         return false;
   2454     }
   2455 
   2456     etb++;
   2457 
   2458     if (!streaming[OUTPUT_PORT]) {
   2459         enum v4l2_buf_type buf_type;
   2460         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2461         int ret;
   2462         ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type);
   2463 
   2464         if (ret) {
   2465             DEBUG_PRINT_ERROR("Failed to call streamon");
   2466             return false;
   2467         } else {
   2468             streaming[OUTPUT_PORT] = true;
   2469         }
   2470     }
   2471     if (m_debug.in_buffer_log) {
   2472         venc_input_log_buffers(bufhdr, fd, plane.data_offset);
   2473     }
   2474 
   2475     return true;
   2476 }
   2477 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
   2478 {
   2479     struct pmem *temp_buffer = NULL;
   2480     struct venc_buffer  frameinfo;
   2481     struct v4l2_buffer buf;
   2482     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   2483     int rc = 0, extra_idx;
   2484     struct OMX_BUFFERHEADERTYPE *bufhdr;
   2485 
   2486     if (buffer == NULL)
   2487         return false;
   2488 
   2489     bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
   2490 
   2491     if (pmem_data_buf) {
   2492         DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
   2493         plane[0].m.userptr = (unsigned long)pmem_data_buf;
   2494     } else {
   2495         DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
   2496         plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
   2497     }
   2498 
   2499     buf.index = index;
   2500     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2501     buf.memory = V4L2_MEMORY_USERPTR;
   2502     plane[0].length = bufhdr->nAllocLen;
   2503     plane[0].bytesused = bufhdr->nFilledLen;
   2504     plane[0].reserved[0] = fd;
   2505     plane[0].reserved[1] = 0;
   2506     plane[0].data_offset = bufhdr->nOffset;
   2507     buf.m.planes = plane;
   2508     buf.length = num_planes;
   2509 
   2510     extra_idx = EXTRADATA_IDX(num_planes);
   2511 
   2512     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   2513         plane[extra_idx].bytesused = 0;
   2514         plane[extra_idx].length = extradata_info.buffer_size;
   2515         plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size);
   2516 #ifdef USE_ION
   2517         plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd;
   2518 #endif
   2519         plane[extra_idx].reserved[1] = extradata_info.buffer_size * index;
   2520         plane[extra_idx].data_offset = 0;
   2521     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   2522         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
   2523         return false;
   2524     }
   2525 
   2526     rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
   2527 
   2528     if (rc) {
   2529         DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver");
   2530         return false;
   2531     }
   2532 
   2533     ftb++;
   2534     return true;
   2535 }
   2536 
   2537 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable)
   2538 {
   2539     struct v4l2_control control;
   2540 
   2541     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
   2542     if(enable) {
   2543         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
   2544     } else {
   2545         control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
   2546     }
   2547 
   2548     DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
   2549     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
   2550         DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
   2551         return false;
   2552     }
   2553     return true;
   2554 }
   2555 
   2556 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
   2557 {
   2558     struct v4l2_control control;
   2559 
   2560     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
   2561     if(enable) {
   2562         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
   2563     } else {
   2564         control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
   2565     }
   2566 
   2567     DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
   2568     if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
   2569         DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
   2570         return false;
   2571     }
   2572     return true;
   2573 }
   2574 
   2575 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
   2576                                     OMX_U32 num_layers)
   2577 {
   2578     struct v4l2_control control;
   2579     control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
   2580     if (type == QOMX_HIERARCHICALCODING_P) {
   2581         control.value = num_layers;
   2582         DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
   2583         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   2584             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
   2585             return false;
   2586         }
   2587         hier_p_layers.numlayers = num_layers;
   2588     } else {
   2589         DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
   2590         return false;
   2591     }
   2592     return true;
   2593 }
   2594 
   2595 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
   2596 {
   2597     struct v4l2_control control;
   2598 
   2599     DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
   2600 
   2601     if (enable == OMX_FALSE) {
   2602         /* No easy way to turn off extradata to the driver
   2603          * at the moment */
   2604         return false;
   2605     }
   2606 
   2607     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   2608     switch (extra_data) {
   2609         case OMX_ExtraDataVideoEncoderSliceInfo:
   2610             control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
   2611             break;
   2612         case OMX_ExtraDataVideoEncoderMBInfo:
   2613             control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
   2614             break;
   2615         default:
   2616             DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
   2617             return false;
   2618     }
   2619 
   2620     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   2621         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
   2622                 (unsigned int)extra_data, errno);
   2623         return false;
   2624     }
   2625 
   2626     return true;
   2627 }
   2628 
   2629 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable)
   2630 {
   2631     struct v4l2_control control;
   2632 
   2633     if (enable) {
   2634         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE;
   2635         control.value = 1;
   2636         DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value);
   2637 
   2638         if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   2639             if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   2640                 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed");
   2641                 return false;
   2642             } else {
   2643                 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value);
   2644                 slice_mode.enable = 1;
   2645             }
   2646         } else {
   2647             DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
   2648                     "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode,
   2649                     m_sVenc_cfg.codectype);
   2650         }
   2651     } else {
   2652         DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled");
   2653     }
   2654 
   2655     return true;
   2656 }
   2657 
   2658 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
   2659 {
   2660     int rc;
   2661     struct v4l2_control control;
   2662     struct v4l2_ext_control ctrl[4];
   2663     struct v4l2_ext_controls controls;
   2664 
   2665     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
   2666     ctrl[0].value = initqp->nQpI;
   2667     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
   2668     ctrl[1].value = initqp->nQpP;
   2669     ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
   2670     ctrl[2].value = initqp->nQpB;
   2671     ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
   2672     ctrl[3].value = initqp->bEnableInitQp;
   2673 
   2674     controls.count = 4;
   2675     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   2676     controls.controls = ctrl;
   2677 
   2678     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
   2679                     controls.controls[0].id, controls.controls[0].value,
   2680                     controls.controls[1].id, controls.controls[1].value,
   2681                     controls.controls[2].id, controls.controls[2].value,
   2682                     controls.controls[3].id, controls.controls[3].value);
   2683 
   2684     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   2685     if (rc) {
   2686         DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
   2687         return false;
   2688     }
   2689 
   2690     init_qp.iframeqp = initqp->nQpI;
   2691     init_qp.pframeqp = initqp->nQpP;
   2692     init_qp.bframeqp = initqp->nQpB;
   2693     init_qp.enableinitqp = initqp->bEnableInitQp;
   2694 
   2695     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
   2696                     controls.controls[0].id, controls.controls[0].value,
   2697                     controls.controls[1].id, controls.controls[1].value,
   2698                     controls.controls[2].id, controls.controls[2].value,
   2699                     controls.controls[3].id, controls.controls[3].value);
   2700     return true;
   2701 }
   2702 
   2703 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp)
   2704 {
   2705     int rc;
   2706     struct v4l2_control control;
   2707 
   2708     control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
   2709     control.value = i_frame_qp;
   2710 
   2711     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   2712     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2713 
   2714     if (rc) {
   2715         DEBUG_PRINT_ERROR("Failed to set control");
   2716         return false;
   2717     }
   2718 
   2719     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   2720     session_qp.iframeqp = control.value;
   2721 
   2722     control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
   2723     control.value = p_frame_qp;
   2724 
   2725     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   2726     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2727 
   2728     if (rc) {
   2729         DEBUG_PRINT_ERROR("Failed to set control");
   2730         return false;
   2731     }
   2732 
   2733     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   2734 
   2735     session_qp.pframeqp = control.value;
   2736 
   2737     if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) ||
   2738             (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
   2739 
   2740         control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
   2741         control.value = b_frame_qp;
   2742 
   2743         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   2744         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2745 
   2746         if (rc) {
   2747             DEBUG_PRINT_ERROR("Failed to set control");
   2748             return false;
   2749         }
   2750 
   2751         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   2752 
   2753         session_qp.bframeqp = control.value;
   2754     }
   2755 
   2756     return true;
   2757 }
   2758 
   2759 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
   2760 {
   2761     int rc;
   2762     struct v4l2_control control;
   2763 
   2764     if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
   2765 
   2766         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
   2767             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
   2768         else
   2769             control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
   2770         control.value = min_qp;
   2771 
   2772         DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
   2773                 control.id, control.value);
   2774         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2775         if (rc) {
   2776             DEBUG_PRINT_ERROR("Failed to set control\n");
   2777             return false;
   2778         }
   2779 
   2780         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
   2781             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
   2782         else
   2783             control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
   2784         control.value = max_qp;
   2785 
   2786         DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
   2787                 control.id, control.value);
   2788         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   2789         if (rc) {
   2790             DEBUG_PRINT_ERROR("Failed to set control\n");
   2791             return false;
   2792         }
   2793     } else {
   2794         DEBUG_PRINT_ERROR("Wrong qp values[%lu %lu], allowed range[%lu %lu]",
   2795             min_qp, max_qp, session_qp_range.minqp, session_qp_range.maxqp);
   2796     }
   2797 
   2798     return true;
   2799 }
   2800 
   2801 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel)
   2802 {
   2803     struct venc_profile requested_profile = {0};
   2804     struct ven_profilelevel requested_level = {0};
   2805     unsigned long mb_per_frame = 0;
   2806     DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u",
   2807             (unsigned int)eProfile, (unsigned int)eLevel);
   2808     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
   2809         ((m_sVenc_cfg.dvs_width + 15) >> 4);
   2810 
   2811     if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
   2812         DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
   2813         return true;
   2814     }
   2815 
   2816     DEBUG_PRINT_LOW("Validating Profile/Level from table");
   2817 
   2818     if (!venc_validate_profile_level(&eProfile, &eLevel)) {
   2819         DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
   2820         return false;
   2821     }
   2822 
   2823     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   2824         DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
   2825                 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile,
   2826                 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple);
   2827 
   2828         if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
   2829             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE;
   2830         } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
   2831             requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE;
   2832         } else {
   2833             DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u",
   2834                     (unsigned int)eProfile);
   2835             return false;
   2836         }
   2837 
   2838         DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
   2839                 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
   2840                 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1,
   2841                 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5);
   2842 
   2843         if (mb_per_frame >= 3600) {
   2844             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
   2845                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   2846 
   2847             if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
   2848                 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   2849         } else {
   2850             switch (eLevel) {
   2851                 case OMX_VIDEO_MPEG4Level0:
   2852                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0;
   2853                     break;
   2854                 case OMX_VIDEO_MPEG4Level0b:
   2855                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B;
   2856                     break;
   2857                 case OMX_VIDEO_MPEG4Level1:
   2858                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1;
   2859                     break;
   2860                 case OMX_VIDEO_MPEG4Level2:
   2861                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2;
   2862                     break;
   2863                 case OMX_VIDEO_MPEG4Level3:
   2864                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3;
   2865                     break;
   2866                 case OMX_VIDEO_MPEG4Level4a:
   2867                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4;
   2868                     break;
   2869                 case OMX_VIDEO_MPEG4Level5:
   2870                     requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   2871                     break;
   2872                 default:
   2873                     return false;
   2874                     // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6
   2875                     break;
   2876             }
   2877         }
   2878     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   2879 
   2880         switch (eProfile) {
   2881             case OMX_VIDEO_H263ProfileBaseline:
   2882                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE;
   2883                 break;
   2884             case OMX_VIDEO_H263ProfileH320Coding:
   2885                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING;
   2886                 break;
   2887             case OMX_VIDEO_H263ProfileBackwardCompatible:
   2888                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE;
   2889                 break;
   2890             case OMX_VIDEO_H263ProfileISWV2:
   2891                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2;
   2892                 break;
   2893             case OMX_VIDEO_H263ProfileISWV3:
   2894                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3;
   2895                 break;
   2896             case OMX_VIDEO_H263ProfileHighCompression:
   2897                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION;
   2898                 break;
   2899             case OMX_VIDEO_H263ProfileInternet:
   2900                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET;
   2901                 break;
   2902             case OMX_VIDEO_H263ProfileInterlace:
   2903                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE;
   2904                 break;
   2905             case OMX_VIDEO_H263ProfileHighLatency:
   2906                 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY;
   2907                 break;
   2908             default:
   2909                 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu",
   2910                         requested_profile.profile);
   2911                 return false;
   2912         }
   2913 
   2914         //profile level
   2915         switch (eLevel) {
   2916             case OMX_VIDEO_H263Level10:
   2917                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0;
   2918                 break;
   2919             case OMX_VIDEO_H263Level20:
   2920                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0;
   2921                 break;
   2922             case OMX_VIDEO_H263Level30:
   2923                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0;
   2924                 break;
   2925             case OMX_VIDEO_H263Level40:
   2926                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0;
   2927                 break;
   2928             case OMX_VIDEO_H263Level45:
   2929                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5;
   2930                 break;
   2931             case OMX_VIDEO_H263Level50:
   2932                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0;
   2933                 break;
   2934             case OMX_VIDEO_H263Level60:
   2935                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0;
   2936                 break;
   2937             case OMX_VIDEO_H263Level70:
   2938                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0;
   2939                 break;
   2940             default:
   2941                 return false;
   2942                 break;
   2943         }
   2944     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   2945         if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
   2946             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
   2947         } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
   2948             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
   2949         } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
   2950             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
   2951         } else if (eProfile == OMX_VIDEO_AVCProfileExtended) {
   2952             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
   2953         } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
   2954             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
   2955         } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) {
   2956             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
   2957         } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) {
   2958             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
   2959         } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) {
   2960             requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
   2961         } else {
   2962             DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu",
   2963                     requested_profile.profile);
   2964             return false;
   2965         }
   2966 
   2967         //profile level
   2968         switch (eLevel) {
   2969             case OMX_VIDEO_AVCLevel1:
   2970                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
   2971                 break;
   2972             case OMX_VIDEO_AVCLevel1b:
   2973                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
   2974                 break;
   2975             case OMX_VIDEO_AVCLevel11:
   2976                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
   2977                 break;
   2978             case OMX_VIDEO_AVCLevel12:
   2979                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
   2980                 break;
   2981             case OMX_VIDEO_AVCLevel13:
   2982                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
   2983                 break;
   2984             case OMX_VIDEO_AVCLevel2:
   2985                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
   2986                 break;
   2987             case OMX_VIDEO_AVCLevel21:
   2988                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
   2989                 break;
   2990             case OMX_VIDEO_AVCLevel22:
   2991                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
   2992                 break;
   2993             case OMX_VIDEO_AVCLevel3:
   2994                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
   2995                 break;
   2996             case OMX_VIDEO_AVCLevel31:
   2997                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
   2998                 break;
   2999             case OMX_VIDEO_AVCLevel32:
   3000                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
   3001                 break;
   3002             case OMX_VIDEO_AVCLevel4:
   3003                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
   3004                 break;
   3005             case OMX_VIDEO_AVCLevel41:
   3006                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
   3007                 break;
   3008             case OMX_VIDEO_AVCLevel42:
   3009                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
   3010                 break;
   3011             case OMX_VIDEO_AVCLevel5:
   3012                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
   3013                 break;
   3014             case OMX_VIDEO_AVCLevel51:
   3015                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
   3016                 break;
   3017             case OMX_VIDEO_AVCLevel52:
   3018                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
   3019                 break;
   3020             case OMX_VIDEO_AVCLevelMax:
   3021                 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
   3022                 break;
   3023             default :
   3024                 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
   3025                         requested_level.level);
   3026                 return false;
   3027                 break;
   3028         }
   3029     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   3030         if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
   3031             DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
   3032                         (unsigned int)eProfile);
   3033             return false;
   3034         }
   3035         requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
   3036         m_profile_set = true;
   3037         switch(eLevel) {
   3038             case OMX_VIDEO_VP8Level_Version0:
   3039                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
   3040                 break;
   3041             case OMX_VIDEO_VP8Level_Version1:
   3042                 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
   3043                 break;
   3044             default:
   3045                 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
   3046                             (unsigned int)eLevel);
   3047                 return false;
   3048                 break;
   3049         }
   3050     }
   3051 
   3052     if (!m_profile_set) {
   3053         int rc;
   3054         struct v4l2_control control;
   3055 
   3056         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   3057             control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
   3058         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   3059             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
   3060         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   3061             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
   3062         } else {
   3063             DEBUG_PRINT_ERROR("Wrong CODEC");
   3064             return false;
   3065         }
   3066 
   3067         control.value = requested_profile.profile;
   3068 
   3069         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3070         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3071 
   3072         if (rc) {
   3073             DEBUG_PRINT_ERROR("Failed to set control");
   3074             return false;
   3075         }
   3076 
   3077         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3078 
   3079         codec_profile.profile = control.value;
   3080         m_profile_set = true;
   3081     }
   3082 
   3083     if (!m_level_set) {
   3084         int rc;
   3085         struct v4l2_control control;
   3086 
   3087         if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   3088             control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
   3089         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   3090             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL;
   3091         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   3092             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
   3093         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   3094             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
   3095         } else {
   3096             DEBUG_PRINT_ERROR("Wrong CODEC");
   3097             return false;
   3098         }
   3099 
   3100         control.value = requested_level.level;
   3101 
   3102         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3103         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3104 
   3105         if (rc) {
   3106             DEBUG_PRINT_ERROR("Failed to set control");
   3107             return false;
   3108         }
   3109 
   3110         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3111 
   3112         profile_level.level = control.value;
   3113         m_level_set = true;
   3114     }
   3115 
   3116     return true;
   3117 }
   3118 
   3119 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes)
   3120 {
   3121 
   3122     struct venc_voptimingcfg vop_timing_cfg;
   3123 
   3124     DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u",
   3125             (unsigned int)TimeIncRes);
   3126 
   3127     vop_timing_cfg.voptime_resolution = TimeIncRes;
   3128 
   3129     voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution;
   3130     return true;
   3131 }
   3132 
   3133 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames)
   3134 {
   3135 
   3136     DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
   3137     int rc;
   3138     struct v4l2_control control;
   3139     int pframe = 0, bframe = 0;
   3140 
   3141     if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
   3142             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
   3143             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
   3144         nBFrames=0;
   3145     }
   3146     if ((display_info.w * display_info.h > OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
   3147         && enable_mv_narrow_searchrange && (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >=
   3148         OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT || is_searchrange_set)) {
   3149         nBFrames=0;
   3150     }
   3151 
   3152     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
   3153     control.value = nPFrames;
   3154     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3155 
   3156     if (rc) {
   3157         DEBUG_PRINT_ERROR("Failed to set control");
   3158         return false;
   3159     }
   3160 
   3161     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3162 
   3163     intra_period.num_pframes = control.value;
   3164     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
   3165     control.value = nBFrames;
   3166     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3167     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3168 
   3169     if (rc) {
   3170         DEBUG_PRINT_ERROR("Failed to set control");
   3171         return false;
   3172     }
   3173 
   3174     intra_period.num_bframes = nBFrames;
   3175     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
   3176 
   3177     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   3178         control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
   3179         control.value = 1;
   3180 
   3181         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3182 
   3183         if (rc) {
   3184             DEBUG_PRINT_ERROR("Failed to set control");
   3185             return false;
   3186         }
   3187 
   3188         idrperiod.idrperiod = 1;
   3189     }
   3190 
   3191     return true;
   3192 }
   3193 
   3194 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod)
   3195 {
   3196     int rc = 0;
   3197     struct v4l2_control control;
   3198     DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
   3199             (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
   3200 
   3201     if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
   3202         DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
   3203         return false;
   3204     }
   3205 
   3206     if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
   3207         DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
   3208         return false;
   3209     }
   3210 
   3211     if (!intra_period.num_bframes)
   3212     intra_period.num_pframes = nPFrames;
   3213     control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
   3214     control.value = nIDRPeriod;
   3215 
   3216     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3217 
   3218     if (rc) {
   3219         DEBUG_PRINT_ERROR("Failed to set control");
   3220         return false;
   3221     }
   3222 
   3223     idrperiod.idrperiod = nIDRPeriod;
   3224     return true;
   3225 }
   3226 
   3227 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level)
   3228 {
   3229     int rc = 0;
   3230     struct v4l2_control control;
   3231 
   3232     DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
   3233 
   3234     if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
   3235             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) {
   3236 
   3237         control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
   3238         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   3239 
   3240         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3241         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3242 
   3243         if (rc) {
   3244             DEBUG_PRINT_ERROR("Failed to set control");
   3245             return false;
   3246         }
   3247 
   3248         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3249         entropy.longentropysel = control.value;
   3250 
   3251         if (i_cabac_level == 0) {
   3252             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0;
   3253         } else if (i_cabac_level == 1) {
   3254             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1;
   3255         } else if (i_cabac_level == 2) {
   3256             control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2;
   3257         }
   3258 
   3259         control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL;
   3260         //control.value = entropy_cfg.cabacmodel;
   3261         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3262         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3263 
   3264         if (rc) {
   3265             DEBUG_PRINT_ERROR("Failed to set control");
   3266             return false;
   3267         }
   3268 
   3269         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3270         entropy.cabacmodel=control.value;
   3271     } else if (!enable) {
   3272         control.value =  V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
   3273         control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   3274         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3275         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3276 
   3277         if (rc) {
   3278             DEBUG_PRINT_ERROR("Failed to set control");
   3279             return false;
   3280         }
   3281 
   3282         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3283         entropy.longentropysel=control.value;
   3284     } else {
   3285         DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile");
   3286         return false;
   3287     }
   3288 
   3289     return true;
   3290 }
   3291 
   3292 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB
   3293 {
   3294     int rc;
   3295     struct v4l2_control control;
   3296     bool status = true;
   3297 
   3298     if ((Codec != OMX_IndexParamVideoH263)  && (nSlicesize)) {
   3299         control.value =  V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB;
   3300     } else {
   3301         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
   3302     }
   3303 
   3304     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   3305     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3306     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3307 
   3308     if (rc) {
   3309         DEBUG_PRINT_ERROR("Failed to set control");
   3310         return false;
   3311     }
   3312 
   3313     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3314     multislice.mslice_mode=control.value;
   3315 
   3316     if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) {
   3317 
   3318         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
   3319         control.value = nSlicesize;
   3320         DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value);
   3321         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3322 
   3323         if (rc) {
   3324             DEBUG_PRINT_ERROR("Failed to set control");
   3325             return false;
   3326         }
   3327 
   3328         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3329         multislice.mslice_size=control.value;
   3330 
   3331     }
   3332 
   3333     return status;
   3334 }
   3335 
   3336 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs)
   3337 {
   3338     bool status = true;
   3339     int rc;
   3340     struct v4l2_control control_mode,control_mbs;
   3341     control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE;
   3342 
   3343     // There is no disabled mode.  Disabled mode is indicated by a 0 count.
   3344     if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) {
   3345         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE;
   3346         return status;
   3347     } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) &&
   3348             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   3349         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC;
   3350         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
   3351         control_mbs.value=irMBs;
   3352     } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) &&
   3353             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   3354         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE;
   3355         control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
   3356         control_mbs.value=irMBs;
   3357     } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
   3358             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
   3359         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
   3360     } else {
   3361         DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
   3362                 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
   3363         return false;
   3364     }
   3365 
   3366     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value);
   3367     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode);
   3368 
   3369     if (rc) {
   3370         DEBUG_PRINT_ERROR("Failed to set control");
   3371         return false;
   3372     }
   3373 
   3374     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
   3375 
   3376     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value);
   3377     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs);
   3378 
   3379     if (rc) {
   3380         DEBUG_PRINT_ERROR("Failed to set control");
   3381         return false;
   3382     }
   3383 
   3384     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value);
   3385 
   3386     intra_refresh.irmode = control_mode.value;
   3387     intra_refresh.mbcount = control_mbs.value;
   3388 
   3389     return status;
   3390 }
   3391 
   3392 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience)
   3393 {
   3394     bool status = true;
   3395     struct venc_headerextension hec_cfg;
   3396     struct venc_multiclicecfg multislice_cfg;
   3397     int rc;
   3398     OMX_U32 resynchMarkerSpacingBytes = 0;
   3399     struct v4l2_control control;
   3400 
   3401     memset(&control, 0, sizeof(control));
   3402 
   3403     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   3404         if (error_resilience->bEnableHEC) {
   3405             hec_cfg.header_extension = 1;
   3406         } else {
   3407             hec_cfg.header_extension = 0;
   3408         }
   3409 
   3410         hec.header_extension = error_resilience->bEnableHEC;
   3411     }
   3412 
   3413     if (error_resilience->bEnableRVLC) {
   3414         DEBUG_PRINT_ERROR("RVLC is not Supported");
   3415         return false;
   3416     }
   3417 
   3418     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
   3419             (error_resilience->bEnableDataPartitioning)) {
   3420         DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
   3421         return false;
   3422     }
   3423 
   3424     if (error_resilience->nResynchMarkerSpacing) {
   3425         resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
   3426         resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
   3427     }
   3428     if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
   3429             (error_resilience->nResynchMarkerSpacing)) {
   3430         multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
   3431         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
   3432         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   3433         control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES;
   3434     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 &&
   3435             error_resilience->bEnableDataPartitioning) {
   3436         multislice_cfg.mslice_mode = VEN_MSLICE_GOB;
   3437         multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
   3438         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   3439         control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB;
   3440     } else {
   3441         multislice_cfg.mslice_mode = VEN_MSLICE_OFF;
   3442         multislice_cfg.mslice_size = 0;
   3443         control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
   3444         control.value =  V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
   3445     }
   3446 
   3447     DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__,
   3448             multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
   3449     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   3450     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3451 
   3452     if (rc) {
   3453        DEBUG_PRINT_ERROR("Failed to set Slice mode control");
   3454         return false;
   3455     }
   3456 
   3457     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   3458     multislice.mslice_mode=control.value;
   3459 
   3460     control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
   3461     control.value = resynchMarkerSpacingBytes;
   3462     DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   3463 
   3464     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3465 
   3466     if (rc) {
   3467        DEBUG_PRINT_ERROR("Failed to set MAX MB control");
   3468         return false;
   3469     }
   3470 
   3471     DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   3472     multislice.mslice_mode = multislice_cfg.mslice_mode;
   3473     multislice.mslice_size = multislice_cfg.mslice_size;
   3474     return status;
   3475 }
   3476 
   3477 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter)
   3478 {
   3479     int rc;
   3480     struct v4l2_control control;
   3481     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE;
   3482 
   3483     if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) {
   3484         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED;
   3485     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) {
   3486         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED;
   3487     } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) {
   3488         control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY;
   3489     }
   3490 
   3491     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3492     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3493 
   3494     if (rc) {
   3495         return false;
   3496     }
   3497 
   3498     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3499 
   3500     dbkfilter.db_mode=control.value;
   3501 
   3502     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA;
   3503     control.value=0;
   3504 
   3505     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3506     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3507 
   3508     if (rc) {
   3509         return false;
   3510     }
   3511 
   3512     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3513     control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA;
   3514     control.value=0;
   3515     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3516     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3517 
   3518     if (rc) {
   3519         return false;
   3520     }
   3521 
   3522     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3523 
   3524 
   3525     dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0;
   3526     return true;
   3527 }
   3528 
   3529 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config)
   3530 {
   3531     DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u",
   3532             (unsigned int)nTargetBitrate);
   3533     struct v4l2_control control;
   3534     int rc = 0;
   3535     control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
   3536     control.value = nTargetBitrate;
   3537 
   3538     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3539     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3540 
   3541     if (rc) {
   3542         DEBUG_PRINT_ERROR("Failed to set control");
   3543         return false;
   3544     }
   3545 
   3546     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3547 
   3548 
   3549     m_sVenc_cfg.targetbitrate = control.value;
   3550     bitrate.target_bitrate = control.value;
   3551 
   3552     if (!config) {
   3553         m_level_set = false;
   3554 
   3555         if (venc_set_profile_level(0, 0)) {
   3556             DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level);
   3557         }
   3558     }
   3559 
   3560     return true;
   3561 }
   3562 
   3563 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config)
   3564 {
   3565     struct v4l2_streamparm parm;
   3566     int rc = 0;
   3567     struct venc_framerate frame_rate_cfg;
   3568     Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator);
   3569     parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3570     parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator;
   3571     parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator;
   3572 
   3573     if (frame_rate_cfg.fps_numerator > 0)
   3574         rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm);
   3575 
   3576     if (rc) {
   3577         DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed");
   3578         return false;
   3579     }
   3580 
   3581     m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator;
   3582     m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator;
   3583 
   3584     if (!config) {
   3585         m_level_set = false;
   3586 
   3587         if (venc_set_profile_level(0, 0)) {
   3588             DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level);
   3589         }
   3590     }
   3591 
   3592     return true;
   3593 }
   3594 
   3595 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
   3596 {
   3597     struct v4l2_format fmt;
   3598     DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
   3599 
   3600     if ((int)color_format == (int)OMX_COLOR_FormatYUV420SemiPlanar ||
   3601             (int)color_format == (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
   3602         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
   3603     } else if ((int)color_format == (int)QOMX_COLOR_FormatYVU420SemiPlanar) {
   3604         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
   3605     } else {
   3606         DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
   3607         m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
   3608         DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set");
   3609     }
   3610 
   3611     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3612     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
   3613     fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
   3614     fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
   3615 
   3616     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   3617         DEBUG_PRINT_ERROR("Failed setting color format %x", color_format);
   3618         return false;
   3619     }
   3620 
   3621     return true;
   3622 }
   3623 
   3624 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh)
   3625 {
   3626     DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh);
   3627 
   3628     if (intra_vop_refresh == OMX_TRUE) {
   3629         struct v4l2_control control;
   3630         int rc;
   3631         control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME;
   3632         control.value = 1;
   3633        DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   3634         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3635 
   3636         if (rc) {
   3637            DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
   3638             return false;
   3639         }
   3640 
   3641        DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   3642     } else {
   3643         DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
   3644     }
   3645 
   3646     return true;
   3647 }
   3648 
   3649 bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
   3650 {
   3651     DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
   3652     struct v4l2_control control;
   3653     int rc;
   3654     control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
   3655     if (enable)
   3656         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
   3657     else
   3658         control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
   3659 
   3660     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   3661     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3662     if (rc) {
   3663         DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
   3664         return false;
   3665     }
   3666     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   3667     deinterlace_enabled = true;
   3668     return true;
   3669 }
   3670 
   3671 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
   3672 {
   3673     DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
   3674     struct v4l2_control control;
   3675     struct v4l2_ext_control ctrl[2];
   3676     struct v4l2_ext_controls controls;
   3677     int rc;
   3678 
   3679     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
   3680     if (enable)
   3681         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
   3682     else
   3683         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
   3684 
   3685     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
   3686     if (count)
   3687         ctrl[1].value = count;
   3688     else
   3689         ctrl[1].value = 1;
   3690 
   3691     controls.count = 2;
   3692     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   3693     controls.controls = ctrl;
   3694 
   3695     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
   3696                     controls.controls[0].id, controls.controls[0].value,
   3697                     controls.controls[1].id, controls.controls[1].value);
   3698 
   3699     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   3700     if (rc) {
   3701         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
   3702         return false;
   3703     }
   3704 
   3705     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
   3706                     controls.controls[0].id, controls.controls[0].value,
   3707                     controls.controls[1].id, controls.controls[1].value);
   3708 
   3709     control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   3710     control.value = V4L2_MPEG_VIDC_EXTRADATA_LTR;
   3711 
   3712     if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
   3713         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
   3714         return false;
   3715     }
   3716     return true;
   3717 }
   3718 
   3719 bool venc_dev::venc_set_useltr()
   3720 {
   3721     DEBUG_PRINT_LOW("venc_use_goldenframe");
   3722     int rc = true;
   3723     struct v4l2_control control;
   3724 
   3725     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
   3726     control.value = 1;
   3727 
   3728     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3729     if (rc) {
   3730         DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
   3731         return false;
   3732     }
   3733 
   3734     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
   3735                     control.id, control.value);
   3736     return true;
   3737 }
   3738 
   3739 bool venc_dev::venc_set_markltr()
   3740 {
   3741     DEBUG_PRINT_LOW("venc_set_goldenframe");
   3742     int rc = true;
   3743     struct v4l2_control control;
   3744 
   3745     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
   3746     control.value = 1;
   3747 
   3748     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3749     if (rc) {
   3750         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
   3751         return false;
   3752     }
   3753 
   3754     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
   3755                     control.id, control.value);
   3756     return true;
   3757 }
   3758 
   3759 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
   3760 {
   3761     DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
   3762     struct v4l2_control control;
   3763     int rc;
   3764     struct v4l2_format fmt;
   3765     struct v4l2_requestbuffers bufreq;
   3766 
   3767     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
   3768     if (rotation_angle == 0)
   3769         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
   3770     else if (rotation_angle == 90)
   3771         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
   3772     else if (rotation_angle == 180)
   3773         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
   3774     else if (rotation_angle == 270)
   3775         control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
   3776     else {
   3777         DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
   3778         return false;
   3779     }
   3780 
   3781     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   3782     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3783     if (rc) {
   3784         DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
   3785         return false;
   3786     }
   3787     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   3788 
   3789     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3790     fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
   3791     fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
   3792     fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
   3793     if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
   3794         DEBUG_PRINT_ERROR("Failed to set format on capture port");
   3795         return false;
   3796     }
   3797 
   3798     m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   3799     bufreq.memory = V4L2_MEMORY_USERPTR;
   3800     bufreq.count = m_sOutput_buff_property.actualcount;
   3801     bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3802     if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
   3803         DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
   3804             return false;
   3805     }
   3806     if (bufreq.count >= m_sOutput_buff_property.mincount)
   3807         m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
   3808 
   3809     return true;
   3810 }
   3811 
   3812 bool venc_dev::venc_set_searchrange()
   3813 {
   3814     DEBUG_PRINT_LOW("venc_set_searchrange");
   3815     struct v4l2_control control;
   3816     struct v4l2_ext_control ctrl[6];
   3817     struct v4l2_ext_controls controls;
   3818     int rc;
   3819 
   3820     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   3821         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
   3822         ctrl[0].value = 16;
   3823         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
   3824         ctrl[1].value = 4;
   3825         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
   3826         ctrl[2].value = 16;
   3827         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
   3828         ctrl[3].value = 4;
   3829         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
   3830         ctrl[4].value = 12;
   3831         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
   3832         ctrl[5].value = 4;
   3833     } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
   3834                (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
   3835         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
   3836         ctrl[0].value = 16;
   3837         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
   3838         ctrl[1].value = 4;
   3839         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
   3840         ctrl[2].value = 16;
   3841         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
   3842         ctrl[3].value = 4;
   3843         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
   3844         ctrl[4].value = 12;
   3845         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
   3846         ctrl[5].value = 4;
   3847     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   3848         ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
   3849         ctrl[0].value = 4;
   3850         ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
   3851         ctrl[1].value = 4;
   3852         ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
   3853         ctrl[2].value = 4;
   3854         ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
   3855         ctrl[3].value = 4;
   3856         ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
   3857         ctrl[4].value = 4;
   3858         ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
   3859         ctrl[5].value = 4;
   3860     } else {
   3861         DEBUG_PRINT_ERROR("Invalid codec type");
   3862         return false;
   3863     }
   3864     controls.count = 6;
   3865     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   3866     controls.controls = ctrl;
   3867 
   3868     DEBUG_PRINT_LOW(" Calling IOCTL set control for"
   3869         "id=%x, val=%d id=%x, val=%d"
   3870         "id=%x, val=%d id=%x, val=%d"
   3871         "id=%x, val=%d id=%x, val=%d",
   3872         controls.controls[0].id, controls.controls[0].value,
   3873         controls.controls[1].id, controls.controls[1].value,
   3874         controls.controls[2].id, controls.controls[2].value,
   3875         controls.controls[3].id, controls.controls[3].value,
   3876         controls.controls[4].id, controls.controls[4].value,
   3877         controls.controls[5].id, controls.controls[5].value);
   3878 
   3879     rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   3880     if (rc) {
   3881         DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
   3882         return false;
   3883     }
   3884     return true;
   3885 }
   3886 
   3887 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate)
   3888 {
   3889     bool status = true;
   3890     struct v4l2_control control;
   3891     int rc = 0;
   3892     control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
   3893 
   3894     switch (eControlRate) {
   3895         case OMX_Video_ControlRateDisable:
   3896             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
   3897             break;
   3898         case OMX_Video_ControlRateVariableSkipFrames:
   3899             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
   3900             break;
   3901         case OMX_Video_ControlRateVariable:
   3902             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
   3903             break;
   3904         case OMX_Video_ControlRateConstantSkipFrames:
   3905             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
   3906             break;
   3907         case OMX_Video_ControlRateConstant:
   3908             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
   3909             break;
   3910         default:
   3911             status = false;
   3912             break;
   3913     }
   3914 
   3915     if (status) {
   3916 
   3917         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3918         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3919 
   3920         if (rc) {
   3921             DEBUG_PRINT_ERROR("Failed to set control");
   3922             return false;
   3923         }
   3924 
   3925         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3926 
   3927         rate_ctrl.rcmode = control.value;
   3928     }
   3929 
   3930     return status;
   3931 }
   3932 
   3933 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
   3934 {
   3935     bool status = true;
   3936     struct v4l2_control control;
   3937     int rc = 0;
   3938     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   3939 
   3940     switch (ePerfLevel) {
   3941     case OMX_QCOM_PerfLevelNominal:
   3942         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   3943         break;
   3944     case OMX_QCOM_PerfLevelTurbo:
   3945         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   3946         break;
   3947     default:
   3948         status = false;
   3949         break;
   3950     }
   3951 
   3952     if (status) {
   3953         DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3954         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3955 
   3956         if (rc) {
   3957             DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
   3958             return false;
   3959         }
   3960 
   3961         DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   3962     }
   3963     return status;
   3964 }
   3965 
   3966 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
   3967 {
   3968     struct v4l2_control control;
   3969     int rc = 0;
   3970     control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
   3971 
   3972     if (enable)
   3973         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
   3974     else
   3975         control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
   3976 
   3977     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
   3978     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3979     if (rc) {
   3980         DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
   3981         return false;
   3982     }
   3983     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
   3984     return true;
   3985 }
   3986 
   3987 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
   3988 {
   3989     struct v4l2_control control;
   3990     int rc = 0;
   3991     control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
   3992     control.value = nPeakBitrate;
   3993 
   3994     DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
   3995 
   3996     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
   3997     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
   3998 
   3999     if (rc) {
   4000         DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
   4001         return false;
   4002     }
   4003 
   4004     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
   4005 
   4006     return true;
   4007 }
   4008 
   4009 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
   4010 {
   4011     bool status = true;
   4012 
   4013     if (eProfile == NULL || eLevel == NULL) {
   4014         return false;
   4015     }
   4016 
   4017     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   4018         switch (codec_profile.profile) {
   4019             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
   4020                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4021                 break;
   4022             case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
   4023                 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   4024                 break;
   4025             default:
   4026                 *eProfile = OMX_VIDEO_MPEG4ProfileMax;
   4027                 status = false;
   4028                 break;
   4029         }
   4030 
   4031         if (!status) {
   4032             return status;
   4033         }
   4034 
   4035         //profile level
   4036         switch (profile_level.level) {
   4037             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0:
   4038                 *eLevel = OMX_VIDEO_MPEG4Level0;
   4039                 break;
   4040             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B:
   4041                 *eLevel = OMX_VIDEO_MPEG4Level0b;
   4042                 break;
   4043             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1:
   4044                 *eLevel = OMX_VIDEO_MPEG4Level1;
   4045                 break;
   4046             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2:
   4047                 *eLevel = OMX_VIDEO_MPEG4Level2;
   4048                 break;
   4049             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3:
   4050                 *eLevel = OMX_VIDEO_MPEG4Level3;
   4051                 break;
   4052             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4:
   4053                 *eLevel = OMX_VIDEO_MPEG4Level4;
   4054                 break;
   4055             case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5:
   4056                 *eLevel = OMX_VIDEO_MPEG4Level5;
   4057                 break;
   4058             default:
   4059                 *eLevel = OMX_VIDEO_MPEG4LevelMax;
   4060                 status =  false;
   4061                 break;
   4062         }
   4063     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   4064         if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) {
   4065             *eProfile = OMX_VIDEO_H263ProfileBaseline;
   4066         } else {
   4067             *eProfile = OMX_VIDEO_H263ProfileMax;
   4068             return false;
   4069         }
   4070 
   4071         switch (profile_level.level) {
   4072             case VEN_LEVEL_H263_10:
   4073                 *eLevel = OMX_VIDEO_H263Level10;
   4074                 break;
   4075             case VEN_LEVEL_H263_20:
   4076                 *eLevel = OMX_VIDEO_H263Level20;
   4077                 break;
   4078             case VEN_LEVEL_H263_30:
   4079                 *eLevel = OMX_VIDEO_H263Level30;
   4080                 break;
   4081             case VEN_LEVEL_H263_40:
   4082                 *eLevel = OMX_VIDEO_H263Level40;
   4083                 break;
   4084             case VEN_LEVEL_H263_45:
   4085                 *eLevel = OMX_VIDEO_H263Level45;
   4086                 break;
   4087             case VEN_LEVEL_H263_50:
   4088                 *eLevel = OMX_VIDEO_H263Level50;
   4089                 break;
   4090             case VEN_LEVEL_H263_60:
   4091                 *eLevel = OMX_VIDEO_H263Level60;
   4092                 break;
   4093             case VEN_LEVEL_H263_70:
   4094                 *eLevel = OMX_VIDEO_H263Level70;
   4095                 break;
   4096             default:
   4097                 *eLevel = OMX_VIDEO_H263LevelMax;
   4098                 status = false;
   4099                 break;
   4100         }
   4101     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4102         switch (codec_profile.profile) {
   4103             case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   4104                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
   4105                 break;
   4106             case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   4107                 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   4108                 break;
   4109             case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   4110                 *eProfile = OMX_VIDEO_AVCProfileMain;
   4111                 break;
   4112             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   4113                 *eProfile = OMX_VIDEO_AVCProfileHigh;
   4114                 break;
   4115             case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   4116                 *eProfile = OMX_VIDEO_AVCProfileExtended;
   4117                 break;
   4118             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   4119                 *eProfile = OMX_VIDEO_AVCProfileHigh10;
   4120                 break;
   4121             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   4122                 *eProfile = OMX_VIDEO_AVCProfileHigh422;
   4123                 break;
   4124             case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   4125                 *eProfile = OMX_VIDEO_AVCProfileHigh444;
   4126                 break;
   4127             default:
   4128                 *eProfile = OMX_VIDEO_AVCProfileMax;
   4129                 status = false;
   4130                 break;
   4131         }
   4132 
   4133         if (!status) {
   4134             return status;
   4135         }
   4136 
   4137         switch (profile_level.level) {
   4138             case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
   4139                 *eLevel = OMX_VIDEO_AVCLevel1;
   4140                 break;
   4141             case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
   4142                 *eLevel = OMX_VIDEO_AVCLevel1b;
   4143                 break;
   4144             case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
   4145                 *eLevel = OMX_VIDEO_AVCLevel11;
   4146                 break;
   4147             case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
   4148                 *eLevel = OMX_VIDEO_AVCLevel12;
   4149                 break;
   4150             case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
   4151                 *eLevel = OMX_VIDEO_AVCLevel13;
   4152                 break;
   4153             case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
   4154                 *eLevel = OMX_VIDEO_AVCLevel2;
   4155                 break;
   4156             case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
   4157                 *eLevel = OMX_VIDEO_AVCLevel21;
   4158                 break;
   4159             case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
   4160                 *eLevel = OMX_VIDEO_AVCLevel22;
   4161                 break;
   4162             case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
   4163                 *eLevel = OMX_VIDEO_AVCLevel3;
   4164                 break;
   4165             case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
   4166                 *eLevel = OMX_VIDEO_AVCLevel31;
   4167                 break;
   4168             case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
   4169                 *eLevel = OMX_VIDEO_AVCLevel32;
   4170                 break;
   4171             case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
   4172                 *eLevel = OMX_VIDEO_AVCLevel4;
   4173                 break;
   4174             case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
   4175                 *eLevel = OMX_VIDEO_AVCLevel41;
   4176                 break;
   4177             case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
   4178                 *eLevel = OMX_VIDEO_AVCLevel42;
   4179                 break;
   4180             case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
   4181                 *eLevel = OMX_VIDEO_AVCLevel5;
   4182                 break;
   4183             case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
   4184                 *eLevel = OMX_VIDEO_AVCLevel51;
   4185                 break;
   4186             case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
   4187                 *eLevel = OMX_VIDEO_AVCLevel52;
   4188                 break;
   4189             default :
   4190                 *eLevel = OMX_VIDEO_AVCLevelMax;
   4191                 status = false;
   4192                 break;
   4193         }
   4194     }
   4195     else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   4196         switch (codec_profile.profile) {
   4197             case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
   4198                 *eProfile = OMX_VIDEO_VP8ProfileMain;
   4199                 break;
   4200             default:
   4201                 *eProfile = OMX_VIDEO_VP8ProfileMax;
   4202                 status = false;
   4203                 break;
   4204         }
   4205         if (!status) {
   4206             return status;
   4207         }
   4208 
   4209         switch (profile_level.level) {
   4210             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
   4211                 *eLevel = OMX_VIDEO_VP8Level_Version0;
   4212                 break;
   4213             case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
   4214                 *eLevel = OMX_VIDEO_VP8Level_Version1;
   4215                 break;
   4216             default:
   4217                 *eLevel = OMX_VIDEO_VP8LevelMax;
   4218                 status = false;
   4219                 break;
   4220         }
   4221     }
   4222 
   4223     return status;
   4224 }
   4225 
   4226 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel)
   4227 {
   4228     OMX_U32 new_profile = 0, new_level = 0;
   4229     unsigned const int *profile_tbl = NULL;
   4230     OMX_U32 mb_per_frame, mb_per_sec;
   4231     bool profile_level_found = false;
   4232 
   4233     DEBUG_PRINT_LOW("Init profile table for respective codec");
   4234 
   4235     //validate the ht,width,fps,bitrate and set the appropriate profile and level
   4236     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
   4237         if (*eProfile == 0) {
   4238             if (!m_profile_set) {
   4239                 *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4240             } else {
   4241                 switch (codec_profile.profile) {
   4242                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
   4243                         *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   4244                         break;
   4245                     case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
   4246                         *eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   4247                         break;
   4248                     default:
   4249                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
   4250                         return false;
   4251                 }
   4252             }
   4253         }
   4254 
   4255         if (*eLevel == 0 && !m_level_set) {
   4256             *eLevel = OMX_VIDEO_MPEG4LevelMax;
   4257         }
   4258 
   4259         if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) {
   4260             profile_tbl = (unsigned int const *)mpeg4_profile_level_table;
   4261         } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
   4262             profile_tbl = (unsigned int const *)
   4263                 (&mpeg4_profile_level_table[MPEG4_ASP_START]);
   4264         } else {
   4265             DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile);
   4266             return false;
   4267         }
   4268     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
   4269         if (*eProfile == 0) {
   4270             if (!m_profile_set) {
   4271                 *eProfile = OMX_VIDEO_AVCProfileBaseline;
   4272             } else {
   4273                 switch (codec_profile.profile) {
   4274                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   4275                         *eProfile = OMX_VIDEO_AVCProfileBaseline;
   4276                         break;
   4277                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   4278                         *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   4279                         break;
   4280                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   4281                         *eProfile = OMX_VIDEO_AVCProfileMain;
   4282                         break;
   4283                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   4284                         *eProfile = OMX_VIDEO_AVCProfileExtended;
   4285                         break;
   4286                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   4287                         *eProfile = OMX_VIDEO_AVCProfileHigh;
   4288                         break;
   4289                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   4290                         *eProfile = OMX_VIDEO_AVCProfileHigh10;
   4291                         break;
   4292                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   4293                         *eProfile = OMX_VIDEO_AVCProfileHigh422;
   4294                         break;
   4295                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   4296                         *eProfile = OMX_VIDEO_AVCProfileHigh444;
   4297                         break;
   4298                     default:
   4299                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
   4300                         return false;
   4301                 }
   4302             }
   4303         }
   4304 
   4305         if (*eLevel == 0 && !m_level_set) {
   4306             *eLevel = OMX_VIDEO_AVCLevelMax;
   4307         }
   4308 
   4309         if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
   4310             (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
   4311             profile_tbl = (unsigned int const *)h264_profile_level_table;
   4312         } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) {
   4313             profile_tbl = (unsigned int const *)
   4314                 (&h264_profile_level_table[H264_HP_START]);
   4315         } else if (*eProfile == OMX_VIDEO_AVCProfileMain) {
   4316             profile_tbl = (unsigned int const *)
   4317                 (&h264_profile_level_table[H264_MP_START]);
   4318         } else {
   4319             DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile);
   4320             return false;
   4321         }
   4322     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
   4323         if (*eProfile == 0) {
   4324             if (!m_profile_set) {
   4325                 *eProfile = OMX_VIDEO_H263ProfileBaseline;
   4326             } else {
   4327                 switch (codec_profile.profile) {
   4328                     case VEN_PROFILE_H263_BASELINE:
   4329                         *eProfile = OMX_VIDEO_H263ProfileBaseline;
   4330                         break;
   4331                     default:
   4332                         DEBUG_PRINT_LOW("%s(): Unknown Error", __func__);
   4333                         return false;
   4334                 }
   4335             }
   4336         }
   4337 
   4338         if (*eLevel == 0 && !m_level_set) {
   4339             *eLevel = OMX_VIDEO_H263LevelMax;
   4340         }
   4341 
   4342         if (*eProfile == OMX_VIDEO_H263ProfileBaseline) {
   4343             profile_tbl = (unsigned int const *)h263_profile_level_table;
   4344         } else {
   4345             DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
   4346             return false;
   4347         }
   4348     } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
   4349         if (*eProfile == 0) {
   4350             *eProfile = OMX_VIDEO_VP8ProfileMain;
   4351         } else {
   4352             switch (codec_profile.profile) {
   4353                 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
   4354                     *eProfile = OMX_VIDEO_VP8ProfileMain;
   4355                     break;
   4356                 default:
   4357                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
   4358                     return false;
   4359             }
   4360         }
   4361         if (*eLevel == 0) {
   4362             switch (profile_level.level) {
   4363                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
   4364                     *eLevel = OMX_VIDEO_VP8Level_Version0;
   4365                     break;
   4366                 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
   4367                     *eLevel = OMX_VIDEO_VP8Level_Version1;
   4368                     break;
   4369                 default:
   4370                     DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
   4371                     return false;
   4372             }
   4373         }
   4374         return true;
   4375     } else {
   4376         DEBUG_PRINT_LOW("Invalid codec type");
   4377         return false;
   4378     }
   4379 
   4380     mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
   4381         ((m_sVenc_cfg.dvs_width + 15)>> 4);
   4382 
   4383     if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) {
   4384         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)
   4385             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   4386 
   4387         if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE)
   4388             profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5;
   4389 
   4390         {
   4391             new_level = profile_level.level;
   4392             new_profile = codec_profile.profile;
   4393             return true;
   4394         }
   4395     }
   4396 
   4397     mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
   4398 
   4399     do {
   4400         if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
   4401             if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
   4402                 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
   4403                     new_level = (int)profile_tbl[3];
   4404                     new_profile = (int)profile_tbl[4];
   4405                     profile_level_found = true;
   4406                     DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (unsigned int)new_profile, (unsigned int)new_level);
   4407                     break;
   4408                 }
   4409             }
   4410         }
   4411 
   4412         profile_tbl = profile_tbl + 5;
   4413     } while (profile_tbl[0] != 0);
   4414 
   4415     if (profile_level_found != true) {
   4416         DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
   4417         return false;
   4418     }
   4419 
   4420     if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
   4421             || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) {
   4422         *eLevel = new_level;
   4423     }
   4424 
   4425     DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
   4426             "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
   4427 
   4428     return true;
   4429 }
   4430 #ifdef _ANDROID_ICS_
   4431 bool venc_dev::venc_set_meta_mode(bool mode)
   4432 {
   4433     metadatamode = mode;
   4434     return true;
   4435 }
   4436 #endif
   4437 
   4438 bool venc_dev::venc_is_video_session_supported(unsigned long width,
   4439         unsigned long height)
   4440 {
   4441     if ((width * height < capability.min_width *  capability.min_height) ||
   4442             (width * height > capability.max_width *  capability.max_height)) {
   4443         DEBUG_PRINT_ERROR(
   4444                 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
   4445                 width, height, capability.min_width, capability.min_height,
   4446                 capability.max_width, capability.max_height);
   4447         return false;
   4448     }
   4449 
   4450     DEBUG_PRINT_LOW("video session supported");
   4451     return true;
   4452 }
   4453