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