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