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