1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of The Linux Foundation nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 --------------------------------------------------------------------------*/ 28 #include<string.h> 29 #include <sys/ioctl.h> 30 #include <sys/prctl.h> 31 #include<unistd.h> 32 #include <fcntl.h> 33 #include "video_encoder_device.h" 34 #include "omx_video_encoder.h" 35 #ifdef USE_ION 36 #include <linux/msm_ion.h> 37 #endif 38 39 #define MPEG4_SP_START 0 40 #define MPEG4_ASP_START (MPEG4_SP_START + 8) 41 #define MPEG4_720P_LEVEL 6 42 #define H263_BP_START 0 43 #define H264_BP_START 0 44 #define H264_HP_START (H264_BP_START + 13) 45 #define H264_MP_START (H264_BP_START + 26) 46 47 /* MPEG4 profile and level table*/ 48 static const unsigned int mpeg4_profile_level_table[][5]= { 49 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 50 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, 51 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, 52 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, 53 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, 54 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, 55 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 56 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 57 {0,0,0,0,0}, 58 59 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 60 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 61 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 62 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 63 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 64 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 65 {0,0,0,0,0}, 66 }; 67 68 /* H264 profile and level table*/ 69 static const unsigned int h264_profile_level_table[][5]= { 70 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 71 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, 72 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, 73 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, 74 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, 75 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, 76 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, 77 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, 78 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, 79 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, 80 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, 81 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, 82 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, 83 {0,0,0,0,0}, 84 85 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, 86 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, 87 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, 88 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, 89 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, 90 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, 91 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, 92 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, 93 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, 94 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, 95 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, 96 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, 97 {0,0,0,0,0}, 98 99 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, 100 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, 101 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, 102 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, 103 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, 104 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, 105 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, 106 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, 107 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, 108 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, 109 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, 110 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, 111 {0,0,0,0,0} 112 113 }; 114 115 /* H263 profile and level table*/ 116 static const unsigned int h263_profile_level_table[][5]= { 117 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 118 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, 119 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, 120 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, 121 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, 122 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, 123 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, 124 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, 125 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 126 {0,0,0,0,0} 127 }; 128 129 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 130 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 131 132 #define BUFFER_LOG_LOC "/data/misc/media" 133 134 //constructor 135 venc_dev::venc_dev(class omx_venc *venc_class) 136 { 137 m_max_allowed_bitrate_check = false; 138 m_eLevel = 0; 139 m_eProfile = 0; 140 pthread_mutex_init(&loaded_start_stop_mlock, NULL); 141 pthread_cond_init (&loaded_start_stop_cond, NULL); 142 memset(&m_debug,0,sizeof(m_debug)); 143 144 char property_value[PROPERTY_VALUE_MAX] = {0}; 145 property_value[0] = '\0'; 146 property_get("vidc.enc.log.in", property_value, "0"); 147 m_debug.in_buffer_log = atoi(property_value); 148 149 property_value[0] = '\0'; 150 property_get("vidc.enc.log.out", property_value, "0"); 151 m_debug.out_buffer_log = atoi(property_value); 152 snprintf(m_debug.log_loc, PROPERTY_VAL_MAX, 153 "%s", BUFFER_LOG_LOC); 154 155 DEBUG_PRINT_LOW("venc_dev constructor"); 156 } 157 158 venc_dev::~venc_dev() 159 { 160 pthread_cond_destroy(&loaded_start_stop_cond); 161 pthread_mutex_destroy(&loaded_start_stop_mlock); 162 DEBUG_PRINT_LOW("venc_dev distructor"); 163 } 164 165 void* async_venc_message_thread (void *input) 166 { 167 struct venc_ioctl_msg ioctl_msg ={NULL,NULL}; 168 struct venc_timeout timeout; 169 struct venc_msg venc_msg; 170 int error_code = 0; 171 omx_venc *omx = reinterpret_cast<omx_venc*>(input); 172 173 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); 174 timeout.millisec = VEN_TIMEOUT_INFINITE; 175 176 while (1) { 177 ioctl_msg.in = NULL; 178 ioctl_msg.out = (void*)&venc_msg; 179 180 /*Wait for a message from the video decoder driver*/ 181 error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg); 182 183 if (error_code == -512) { // ERESTARTSYS 184 DEBUG_PRINT_ERROR("ERESTARTSYS received in ioctl read next msg!"); 185 } else if (error_code <0) { 186 DEBUG_PRINT_LOW("ioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed"); 187 break; 188 } else if (omx->async_message_process(input,&venc_msg) < 0) { 189 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 190 break; 191 } 192 } 193 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit"); 194 return NULL; 195 } 196 197 int venc_dev::venc_extradata_log_buffers(char *buffer_addr) 198 { 199 return OMX_ErrorUnsupportedSetting; 200 } 201 202 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len) 203 { 204 if (m_debug.out_buffer_log && !m_debug.outfile) { 205 int size = 0; 206 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) { 207 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.m4v", 208 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 209 } else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) { 210 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.264", 211 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 212 } else if(m_sVenc_cfg.codectype == VENC_CODEC_H263) { 213 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.263", 214 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 215 } else if(m_sVenc_cfg.codectype == VENC_CODEC_VP8) { 216 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.ivf", 217 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 218 } 219 if ((size > PROPERTY_VALUE_MAX) || (size < 0)) { 220 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d", 221 m_debug.outfile_name, size); 222 return -1; 223 } 224 m_debug.outfile = fopen(m_debug.outfile_name, "ab"); 225 if (!m_debug.outfile) { 226 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d", 227 m_debug.outfile_name, errno); 228 m_debug.outfile_name[0] = '\0'; 229 return -1; 230 } 231 } 232 if (m_debug.outfile && buffer_len) { 233 DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len); 234 fwrite(buffer_addr, buffer_len, 1, m_debug.outfile); 235 } 236 return 0; 237 } 238 239 bool venc_dev::venc_get_output_log_flag() 240 { 241 return (m_debug.out_buffer_log == 1); 242 } 243 244 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, void *pmem_data_buf, int framelen) { 245 if (!m_debug.infile) { 246 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%d_%d_%p.yuv", 247 m_debug.log_loc, m_sVenc_cfg.input_width, 248 m_sVenc_cfg.input_height, this); 249 if ((size > PROPERTY_VALUE_MAX) || (size < 0)) { 250 DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d", 251 m_debug.infile_name, size); 252 return -1; 253 } 254 m_debug.infile = fopen (m_debug.infile_name, "ab"); 255 if (!m_debug.infile) { 256 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile); 257 m_debug.infile_name[0] = '\0'; 258 return -1; 259 } 260 } 261 if (m_debug.infile && pbuffer && pbuffer->nFilledLen) { 262 #ifdef MAX_RES_1080P 263 int y_size = 0; 264 int c_offset = 0; 265 unsigned char *buf_addr = NULL; 266 267 y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height; 268 //chroma offset is y_size aligned to the 2k boundary 269 c_offset= (y_size + 2047) & (~(2047)); 270 271 if (pmem_data_buf) { 272 DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 273 buf_addr = (OMX_U8 *)pmem_data_buf; 274 } else { 275 DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 276 buf_addr = (unsigned char *)mmap(NULL, 277 ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[2], 278 PROT_READ|PROT_WRITE, MAP_SHARED, 279 ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[0], 0); 280 } 281 282 if (m_debug.infile) { 283 fwrite((const char *)buf_addr, y_size, 1, m_debug.infile); 284 fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1, m_debug.infile); 285 } 286 287 if (!pmem_data_buf) { 288 munmap (buf_addr, ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[2]); 289 } 290 #else 291 if (m_debug.infile) { 292 OMX_U8* ptrbuffer = NULL; 293 if (pmem_data_buf) { 294 DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 295 ptrbuffer = (OMX_U8 *)pmem_data_buf; 296 } else { 297 DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 298 ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; 299 } 300 fwrite((const char *)ptrbuffer, framelen, 1, m_debug.infile); 301 } 302 303 #endif 304 } 305 return 0; 306 } 307 308 bool venc_dev::venc_open(OMX_U32 codec) 309 { 310 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 311 int r; 312 unsigned int alignment = 0,buffer_size = 0, temp =0; 313 314 m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); 315 316 if (m_nDriver_fd == 0) { 317 DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again"); 318 m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); 319 } 320 321 if ((int)m_nDriver_fd < 0) { 322 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure"); 323 return false; 324 } 325 326 DEBUG_PRINT_LOW("m_nDriver_fd = %d", m_nDriver_fd); 327 #ifdef SINGLE_ENCODER_INSTANCE 328 OMX_U32 num_instances = 0; 329 ioctl_msg.in = NULL; 330 ioctl_msg.out = &num_instances; 331 332 if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 ) { 333 DEBUG_PRINT_ERROR("ERROR: Request number of encoder instances failed"); 334 } else if (num_instances > 1) { 335 DEBUG_PRINT_ERROR("Second encoder instance rejected!"); 336 venc_close(); 337 return false; 338 } 339 340 #endif 341 // set the basic configuration of the video encoder driver 342 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; 343 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; 344 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; 345 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; 346 m_sVenc_cfg.fps_num = 30; 347 m_sVenc_cfg.fps_den = 1; 348 m_sVenc_cfg.targetbitrate = 64000; 349 #ifdef MAX_RES_1080P 350 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; 351 #else 352 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12; 353 #endif 354 // initializing QP range parameters 355 qp_range.minqp = 2; 356 357 if (codec == OMX_VIDEO_CodingAVC) 358 qp_range.maxqp = 51; 359 else 360 qp_range.maxqp = 31; 361 362 if (codec == OMX_VIDEO_CodingMPEG4) { 363 m_sVenc_cfg.codectype = VEN_CODEC_MPEG4; 364 codec_profile.profile = VEN_PROFILE_MPEG4_SP; 365 profile_level.level = VEN_LEVEL_MPEG4_2; 366 } else if (codec == OMX_VIDEO_CodingH263) { 367 m_sVenc_cfg.codectype = VEN_CODEC_H263; 368 codec_profile.profile = VEN_PROFILE_H263_BASELINE; 369 profile_level.level = VEN_LEVEL_H263_20; 370 } 371 372 if (codec == OMX_VIDEO_CodingAVC) { 373 m_sVenc_cfg.codectype = VEN_CODEC_H264; 374 codec_profile.profile = VEN_PROFILE_H264_BASELINE; 375 profile_level.level = VEN_LEVEL_H264_1p1; 376 } 377 378 ioctl_msg.in = (void*)&m_sVenc_cfg; 379 ioctl_msg.out = NULL; 380 381 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 ) { 382 DEBUG_PRINT_ERROR("ERROR: Request for setting base configuration failed"); 383 return false; 384 } 385 386 // Get the I/P and O/P buffer requirements 387 ioctl_msg.in = NULL; 388 ioctl_msg.out = (void*)&m_sInput_buff_property; 389 390 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 391 DEBUG_PRINT_ERROR("ERROR: Request for getting i/p buffer requirement failed"); 392 return false; 393 } 394 395 ioctl_msg.in = NULL; 396 ioctl_msg.out = (void*)&m_sOutput_buff_property; 397 398 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 399 DEBUG_PRINT_ERROR("ERROR: Request for getting o/p buffer requirement failed"); 400 return false; 401 } 402 403 m_profile_set = false; 404 m_level_set = false; 405 406 if (venc_set_profile_level(0, 0)) { 407 DEBUG_PRINT_HIGH("%s(): Init Profile/Level setting success", 408 __func__); 409 } 410 411 recon_buffers_count = MAX_RECON_BUFFERS; 412 ltrmode.ltr_mode = 0; 413 ltrcount.ltr_count = 0; 414 ltrperiod.ltr_period = 0; 415 416 return true; 417 } 418 419 void venc_dev::venc_close() 420 { 421 DEBUG_PRINT_LOW("venc_close: fd = %d", m_nDriver_fd); 422 423 if ((int)m_nDriver_fd >= 0) { 424 DEBUG_PRINT_HIGH("venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG"); 425 (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG, 426 NULL); 427 DEBUG_PRINT_LOW("Calling close()"); 428 close(m_nDriver_fd); 429 m_nDriver_fd = -1; 430 } 431 432 if (m_debug.infile) { 433 fclose(m_debug.infile); 434 m_debug.infile = NULL; 435 } 436 if (m_debug.outfile) { 437 fclose(m_debug.outfile); 438 m_debug.outfile = NULL; 439 } 440 441 } 442 443 bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, 444 unsigned long *actual_buff_count, 445 unsigned long *buff_size, 446 unsigned long port) 447 { 448 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 449 unsigned long temp_count = 0; 450 451 if (port == 0) { 452 if (*actual_buff_count > m_sInput_buff_property.mincount) { 453 temp_count = m_sInput_buff_property.actualcount; 454 m_sInput_buff_property.actualcount = *actual_buff_count; 455 ioctl_msg.in = (void*)&m_sInput_buff_property; 456 ioctl_msg.out = NULL; 457 458 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 459 DEBUG_PRINT_ERROR("ERROR: Request for setting i/p buffer requirement failed"); 460 m_sInput_buff_property.actualcount = temp_count; 461 return false; 462 } 463 464 DEBUG_PRINT_LOW("I/P Count set to %lu", *actual_buff_count); 465 } 466 } else { 467 if (*actual_buff_count > m_sOutput_buff_property.mincount) { 468 temp_count = m_sOutput_buff_property.actualcount; 469 m_sOutput_buff_property.actualcount = *actual_buff_count; 470 ioctl_msg.in = (void*)&m_sOutput_buff_property; 471 ioctl_msg.out = NULL; 472 473 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 474 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer requirement failed"); 475 m_sOutput_buff_property.actualcount = temp_count; 476 return false; 477 } 478 479 DEBUG_PRINT_LOW("O/P Count set to %lu", *actual_buff_count); 480 } 481 } 482 483 return true; 484 485 } 486 487 bool venc_dev::venc_loaded_start() 488 { 489 struct timespec ts; 490 int status = 0; 491 492 if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0) { 493 DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed"); 494 return false; 495 } 496 497 if (clock_gettime(CLOCK_REALTIME, &ts) < 0) { 498 DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__); 499 return false; 500 } 501 502 ts.tv_sec += 1; 503 pthread_mutex_lock(&loaded_start_stop_mlock); 504 DEBUG_PRINT_LOW("%s: wait on start done", __func__); 505 status = pthread_cond_timedwait(&loaded_start_stop_cond, 506 &loaded_start_stop_mlock, &ts); 507 508 if (status != 0) { 509 DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__, 510 status, strerror(status)); 511 pthread_mutex_unlock(&loaded_start_stop_mlock); 512 return false; 513 } 514 515 DEBUG_PRINT_LOW("%s: wait over on start done", __func__); 516 pthread_mutex_unlock(&loaded_start_stop_mlock); 517 DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__); 518 return true; 519 } 520 521 bool venc_dev::venc_loaded_stop() 522 { 523 struct timespec ts; 524 int status = 0; 525 526 if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0) { 527 DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed"); 528 return false; 529 } 530 531 if (clock_gettime(CLOCK_REALTIME, &ts) < 0) { 532 DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__); 533 return false; 534 } 535 536 ts.tv_sec += 1; 537 pthread_mutex_lock(&loaded_start_stop_mlock); 538 DEBUG_PRINT_LOW("%s: wait on stop done", __func__); 539 status = pthread_cond_timedwait(&loaded_start_stop_cond, 540 &loaded_start_stop_mlock, &ts); 541 542 if (status != 0) { 543 DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__, 544 status, strerror(status)); 545 pthread_mutex_unlock(&loaded_start_stop_mlock); 546 return false; 547 } 548 549 DEBUG_PRINT_LOW("%s: wait over on stop done", __func__); 550 pthread_mutex_unlock(&loaded_start_stop_mlock); 551 DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__); 552 return true; 553 } 554 555 bool venc_dev::venc_loaded_start_done() 556 { 557 pthread_mutex_lock(&loaded_start_stop_mlock); 558 DEBUG_PRINT_LOW("%s: signal start done", __func__); 559 pthread_cond_signal(&loaded_start_stop_cond); 560 pthread_mutex_unlock(&loaded_start_stop_mlock); 561 return true; 562 } 563 564 bool venc_dev::venc_loaded_stop_done() 565 { 566 pthread_mutex_lock(&loaded_start_stop_mlock); 567 DEBUG_PRINT_LOW("%s: signal stop done", __func__); 568 pthread_cond_signal(&loaded_start_stop_cond); 569 pthread_mutex_unlock(&loaded_start_stop_mlock); 570 return true; 571 } 572 573 bool venc_dev::venc_get_seq_hdr(void *buffer, 574 unsigned buffer_size, OMX_U32 *header_len) 575 { 576 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 577 int i = 0; 578 DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr"); 579 venc_seqheader seq_in, seq_out; 580 seq_in.hdrlen = 0; 581 seq_in.bufsize = buffer_size; 582 seq_in.hdrbufptr = (unsigned char*)buffer; 583 584 if (seq_in.hdrbufptr == NULL) { 585 DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed"); 586 return false; 587 } 588 589 DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr, 590 seq_in.bufsize, seq_in.hdrlen); 591 592 ioctl_msg.in = (void*)&seq_in; 593 ioctl_msg.out = (void*)&seq_out; 594 595 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0) { 596 DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed"); 597 return false; 598 } 599 600 if (seq_out.hdrlen == 0) { 601 DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header"); 602 DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr, 603 seq_out.bufsize, seq_out.hdrlen); 604 return false; 605 } 606 607 *header_len = seq_out.hdrlen; 608 DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr, 609 seq_out.bufsize, seq_out.hdrlen); 610 611 return true; 612 } 613 614 bool venc_dev::venc_get_capability_ltrcount(unsigned long *min, 615 unsigned long *max, unsigned long *step_size) 616 { 617 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 618 venc_range cap_ltr_count; 619 ioctl_msg.in = NULL; 620 ioctl_msg.out = (void*)&cap_ltr_count; 621 622 if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_CAPABILITY_LTRCOUNT, 623 (void*)&ioctl_msg) < 0) { 624 DEBUG_PRINT_ERROR("ERROR: Get LTR Capability failed"); 625 return false; 626 } else { 627 *min = cap_ltr_count.min; 628 *max = cap_ltr_count.max; 629 *step_size = cap_ltr_count.step_size; 630 DEBUG_PRINT_HIGH("LTR Capability: min=%x, max=%d, step_size=%d", 631 *min, *max, *step_size); 632 } 633 634 return true; 635 } 636 637 bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, 638 unsigned long *actual_buff_count, 639 unsigned long *buff_size, 640 unsigned long port) 641 { 642 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 643 644 if (port == 0) { 645 ioctl_msg.in = NULL; 646 ioctl_msg.out = (void*)&m_sInput_buff_property; 647 648 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 649 DEBUG_PRINT_ERROR("ERROR: Request for getting i/p buffer requirement failed"); 650 return false; 651 } 652 653 *min_buff_count = m_sInput_buff_property.mincount; 654 *actual_buff_count = m_sInput_buff_property.actualcount; 655 #ifdef USE_ION 656 // For ION memory allocations of the allocated buffer size 657 // must be 4k aligned, hence aligning the input buffer 658 // size to 4k. 659 m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) 660 & (~4095); 661 #endif 662 *buff_size = m_sInput_buff_property.datasize; 663 } else { 664 ioctl_msg.in = NULL; 665 ioctl_msg.out = (void*)&m_sOutput_buff_property; 666 667 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 668 DEBUG_PRINT_ERROR("ERROR: Request for getting o/p buffer requirement failed"); 669 return false; 670 } 671 672 *min_buff_count = m_sOutput_buff_property.mincount; 673 *actual_buff_count = m_sOutput_buff_property.actualcount; 674 *buff_size = m_sOutput_buff_property.datasize; 675 } 676 677 return true; 678 679 } 680 681 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) 682 { 683 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 684 DEBUG_PRINT_LOW("venc_set_param:: venc-720p"); 685 686 switch (index) { 687 case OMX_IndexParamPortDefinition: 688 { 689 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 690 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 691 DEBUG_PRINT_HIGH("venc_set_param: OMX_IndexParamPortDefinition"); 692 693 if (portDefn->nPortIndex == PORT_INDEX_IN) { 694 695 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) { 696 return false; 697 } 698 699 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) { 700 return false; 701 } 702 703 DEBUG_PRINT_LOW("Basic parameter has changed"); 704 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; 705 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; 706 707 ioctl_msg.in = (void*)&m_sVenc_cfg; 708 ioctl_msg.out = NULL; 709 710 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) { 711 DEBUG_PRINT_ERROR("ERROR: Request for setting base config failed"); 712 return false; 713 } 714 715 DEBUG_PRINT_HIGH("WxH (%dx%d), codec (%d), fps(nr/dr) (%d/%d), bitrate (%d), " 716 "color_format (%d)", m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, 717 m_sVenc_cfg.codectype, m_sVenc_cfg.fps_num, m_sVenc_cfg.fps_den, 718 m_sVenc_cfg.targetbitrate, m_sVenc_cfg.inputformat); 719 720 DEBUG_PRINT_LOW("Updating the buffer count/size for the new resolution"); 721 ioctl_msg.in = NULL; 722 ioctl_msg.out = (void*)&m_sInput_buff_property; 723 724 if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 725 DEBUG_PRINT_ERROR("ERROR: Request for getting i/p bufreq failed"); 726 return false; 727 } 728 729 DEBUG_PRINT_HIGH("Got updated m_sInput_buff_property values: " 730 "datasize = %u, maxcount = %u, actualcnt = %u, " 731 "mincount = %u", m_sInput_buff_property.datasize, 732 m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount, 733 m_sInput_buff_property.mincount); 734 735 ioctl_msg.in = NULL; 736 ioctl_msg.out = (void*)&m_sOutput_buff_property; 737 738 if (ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 739 DEBUG_PRINT_ERROR("ERROR: Request for getting o/p bufreq failed"); 740 return false; 741 } 742 743 DEBUG_PRINT_HIGH("Got updated m_sOutput_buff_property values: " 744 "datasize = %u, maxcount = %u, actualcnt = %u, " 745 "mincount = %u", m_sOutput_buff_property.datasize, 746 m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount, 747 m_sOutput_buff_property.mincount); 748 ioctl_msg.in = (void*)&m_sOutput_buff_property; 749 ioctl_msg.out = NULL; 750 751 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 752 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p bufreq failed"); 753 return false; 754 } 755 756 if ((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) && 757 (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) { 758 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; 759 ioctl_msg.in = (void*)&m_sInput_buff_property; 760 ioctl_msg.out = NULL; 761 762 if (ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 763 DEBUG_PRINT_ERROR("ERROR: Request for setting i/p buffer requirements failed"); 764 return false; 765 } 766 } 767 768 if (m_sInput_buff_property.datasize != portDefn->nBufferSize) { 769 DEBUG_PRINT_ERROR("WARNING: Requested i/p bufsize[%u]," 770 "Driver's updated i/p bufsize = %u", portDefn->nBufferSize, 771 m_sInput_buff_property.datasize); 772 } 773 774 m_level_set = false; 775 776 if (venc_set_profile_level(0, 0)) { 777 DEBUG_PRINT_LOW("%s(): Profile/Level setting success", __func__); 778 } 779 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) { 780 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) { 781 return false; 782 } 783 784 if ( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) 785 && 786 (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual) 787 && 788 (m_sOutput_buff_property.datasize == portDefn->nBufferSize) 789 ) { 790 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 791 ioctl_msg.in = (void*)&m_sOutput_buff_property; 792 ioctl_msg.out = NULL; 793 794 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 795 DEBUG_PRINT_ERROR("ERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed"); 796 return false; 797 } 798 } else { 799 DEBUG_PRINT_ERROR("ERROR: Setting Output buffer requirements failed"); 800 return false; 801 } 802 } else { 803 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); 804 } 805 806 break; 807 } 808 case OMX_IndexParamVideoPortFormat: 809 { 810 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; 811 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 812 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat"); 813 814 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) { 815 if (!venc_set_color_format(portFmt->eColorFormat)) { 816 return false; 817 } 818 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 819 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) { 820 return false; 821 } 822 } else { 823 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); 824 } 825 826 break; 827 } 828 case OMX_IndexParamVideoBitrate: 829 { 830 OMX_VIDEO_PARAM_BITRATETYPE* pParam; 831 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 832 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate"); 833 834 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 835 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) { 836 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed"); 837 return false; 838 } 839 840 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) { 841 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed"); 842 return false; 843 } 844 } else { 845 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); 846 } 847 848 break; 849 } 850 case OMX_IndexParamVideoMpeg4: 851 { 852 OMX_VIDEO_PARAM_MPEG4TYPE* pParam; 853 OMX_U32 bFrames = 0; 854 855 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 856 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4"); 857 858 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 859 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) { 860 DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed"); 861 return false; 862 } 863 864 m_profile_set = false; 865 m_level_set = false; 866 867 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 868 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level"); 869 return false; 870 } 871 872 #ifdef MAX_RES_1080P 873 else { 874 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 875 if (pParam->nBFrames) { 876 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); 877 bFrames = 1; 878 } 879 } else { 880 if (pParam->nBFrames) { 881 DEBUG_PRINT_ERROR("Warning: B frames not supported"); 882 bFrames = 0; 883 } 884 } 885 } 886 887 #endif 888 889 if (!venc_set_intra_period (pParam->nPFrames,bFrames)) { 890 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 891 return false; 892 } 893 894 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) { 895 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config"); 896 return false; 897 } 898 } else { 899 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); 900 } 901 902 break; 903 } 904 case OMX_IndexParamVideoH263: 905 { 906 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 907 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263"); 908 OMX_U32 bFrames = 0; 909 910 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 911 m_profile_set = false; 912 m_level_set = false; 913 914 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 915 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level"); 916 return false; 917 } 918 919 if (pParam->nBFrames) 920 DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263"); 921 922 if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) { 923 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 924 return false; 925 } 926 } else { 927 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263"); 928 } 929 930 break; 931 } 932 case OMX_IndexParamVideoAvc: 933 { 934 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc"); 935 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 936 OMX_U32 bFrames = 0; 937 938 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 939 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d", 940 pParam->eProfile,pParam->eLevel); 941 942 m_profile_set = false; 943 m_level_set = false; 944 945 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) { 946 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d", 947 pParam->eProfile, pParam->eLevel); 948 return false; 949 } 950 951 #ifdef MAX_RES_1080P 952 else { 953 if (pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) { 954 if (pParam->nBFrames) { 955 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); 956 bFrames = 1; 957 } 958 } else { 959 if (pParam->nBFrames) { 960 DEBUG_PRINT_ERROR("Warning: B frames not supported"); 961 bFrames = 0; 962 } 963 } 964 } 965 966 #endif 967 968 if (!venc_set_intra_period (pParam->nPFrames, bFrames)) { 969 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 970 return false; 971 } 972 973 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) { 974 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed"); 975 return false; 976 } 977 978 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) { 979 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed"); 980 return false; 981 } 982 983 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) { 984 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config"); 985 return false; 986 } 987 } else { 988 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); 989 } 990 991 //TBD, lot of other variables to be updated, yet to decide 992 break; 993 } 994 case OMX_IndexParamVideoIntraRefresh: 995 { 996 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh"); 997 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = 998 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; 999 1000 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1001 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) { 1002 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 1003 return false; 1004 } 1005 } else { 1006 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); 1007 } 1008 1009 break; 1010 } 1011 case OMX_IndexParamVideoErrorCorrection: 1012 { 1013 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection"); 1014 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = 1015 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; 1016 1017 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1018 if (venc_set_error_resilience(error_resilience) == false) { 1019 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 1020 return false; 1021 } 1022 } else { 1023 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); 1024 } 1025 1026 break; 1027 } 1028 case OMX_IndexParamVideoProfileLevelCurrent: 1029 { 1030 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent"); 1031 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = 1032 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 1033 1034 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1035 m_profile_set = false; 1036 m_level_set = false; 1037 1038 if (!venc_set_profile_level (profile_level->eProfile, 1039 profile_level->eLevel)) { 1040 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level"); 1041 return false; 1042 } 1043 } else { 1044 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); 1045 } 1046 1047 break; 1048 } 1049 case OMX_IndexParamVideoQuantization: 1050 { 1051 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization"); 1052 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = 1053 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; 1054 1055 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1056 if (venc_set_session_qp (session_qp->nQpI, 1057 session_qp->nQpP) == false) { 1058 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed"); 1059 return false; 1060 } 1061 } else { 1062 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); 1063 } 1064 1065 break; 1066 } 1067 1068 case OMX_QcomIndexParamVideoQPRange: 1069 { 1070 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange"); 1071 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = 1072 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData; 1073 1074 if (qp_range->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1075 if (venc_set_qp_range (qp_range->minQP, 1076 qp_range->maxQP) == false) { 1077 DEBUG_PRINT_ERROR("ERROR: Setting QP Range failed"); 1078 return false; 1079 } 1080 } else { 1081 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange"); 1082 } 1083 1084 break; 1085 } 1086 1087 case OMX_ExtraDataVideoEncoderSliceInfo: 1088 { 1089 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); 1090 OMX_U32 extra_data = *(OMX_U32 *)paramData; 1091 1092 if (venc_set_extradata(extra_data) == false) { 1093 DEBUG_PRINT_ERROR("ERROR: Setting " 1094 "OMX_ExtraDataVideoEncoderSliceInfo failed"); 1095 return false; 1096 } 1097 1098 break; 1099 } 1100 case OMX_ExtraDataVideoLTRInfo: 1101 { 1102 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoLTRInfo"); 1103 OMX_U32 extra_data = *(OMX_U32 *)paramData; 1104 1105 if (venc_set_extradata(extra_data) == false) { 1106 DEBUG_PRINT_ERROR("ERROR: Setting " 1107 "OMX_ExtraDataVideoLTRInfo failed"); 1108 return false; 1109 } 1110 1111 break; 1112 } 1113 case OMX_QcomIndexEnableSliceDeliveryMode: 1114 { 1115 QOMX_EXTNINDEX_PARAMTYPE* pParam = 1116 (QOMX_EXTNINDEX_PARAMTYPE*)paramData; 1117 1118 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1119 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) { 1120 DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); 1121 return OMX_ErrorUnsupportedSetting; 1122 } 1123 } else { 1124 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " 1125 "called on wrong port(%d)", pParam->nPortIndex); 1126 return OMX_ErrorBadPortIndex; 1127 } 1128 1129 break; 1130 } 1131 case OMX_QcomIndexEnableH263PlusPType: 1132 { 1133 QOMX_EXTNINDEX_PARAMTYPE* pParam = 1134 (QOMX_EXTNINDEX_PARAMTYPE*)paramData; 1135 DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType"); 1136 1137 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1138 if (venc_set_plusptype(pParam->bEnable) == false) { 1139 DEBUG_PRINT_ERROR("Setting PlusPType failed for H263"); 1140 return OMX_ErrorUnsupportedSetting; 1141 } 1142 } else { 1143 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableH263PlusPType " 1144 "called on wrong port(%d)", pParam->nPortIndex); 1145 return OMX_ErrorBadPortIndex; 1146 } 1147 1148 break; 1149 } 1150 case QOMX_IndexParamVideoLTRMode: 1151 { 1152 QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam = 1153 (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData; 1154 1155 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1156 if (!venc_set_ltrmode(pParam->eLTRMode)) { 1157 DEBUG_PRINT_ERROR("Setting ltr mode failed"); 1158 return OMX_ErrorUnsupportedSetting; 1159 } 1160 } else { 1161 DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRMode " 1162 "called on wrong port(%d)", pParam->nPortIndex); 1163 return OMX_ErrorBadPortIndex; 1164 } 1165 1166 break; 1167 } 1168 case QOMX_IndexParamVideoLTRCount: 1169 { 1170 QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam = 1171 (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData; 1172 1173 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1174 if (!venc_set_ltrcount(pParam->nCount)) { 1175 DEBUG_PRINT_ERROR("Setting ltr count failed"); 1176 return OMX_ErrorUnsupportedSetting; 1177 } 1178 } else { 1179 DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRCount " 1180 "called on wrong port(%d)", pParam->nPortIndex); 1181 return OMX_ErrorBadPortIndex; 1182 } 1183 1184 break; 1185 } 1186 case OMX_IndexParamVideoSliceFMO: 1187 default: 1188 DEBUG_PRINT_ERROR("venc_set_param: Unsupported index 0x%x", index); 1189 break; 1190 } 1191 1192 return true; 1193 } 1194 1195 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) 1196 { 1197 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1198 DEBUG_PRINT_LOW("Inside venc_set_config"); 1199 1200 switch (index) { 1201 case OMX_IndexConfigVideoBitrate: 1202 { 1203 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) 1204 configData; 1205 1206 if (m_max_allowed_bitrate_check && 1207 !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate)) { 1208 DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed"); 1209 return false; 1210 } 1211 1212 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate"); 1213 1214 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1215 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) { 1216 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed"); 1217 return false; 1218 } 1219 } else { 1220 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); 1221 } 1222 1223 break; 1224 } 1225 case OMX_IndexConfigVideoFramerate: 1226 { 1227 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) 1228 configData; 1229 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate"); 1230 1231 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1232 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) { 1233 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed"); 1234 return false; 1235 } 1236 } else { 1237 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 1238 } 1239 1240 break; 1241 } 1242 case QOMX_IndexConfigVideoIntraperiod: 1243 { 1244 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod"); 1245 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = 1246 (QOMX_VIDEO_INTRAPERIODTYPE *)configData; 1247 1248 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1249 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) { 1250 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1251 return false; 1252 } 1253 } 1254 1255 break; 1256 } 1257 case OMX_IndexConfigVideoIntraVOPRefresh: 1258 { 1259 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) 1260 configData; 1261 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); 1262 1263 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1264 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) { 1265 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed"); 1266 return false; 1267 } 1268 } else { 1269 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 1270 } 1271 1272 break; 1273 } 1274 case OMX_IndexConfigCommonRotate: 1275 { 1276 OMX_CONFIG_ROTATIONTYPE *config_rotation = 1277 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 1278 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1279 OMX_U32 nFrameWidth; 1280 1281 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims"); 1282 nFrameWidth = m_sVenc_cfg.input_width; 1283 m_sVenc_cfg.input_width = m_sVenc_cfg.input_height; 1284 m_sVenc_cfg.input_height = nFrameWidth; 1285 ioctl_msg.in = (void*)&m_sVenc_cfg; 1286 ioctl_msg.out = NULL; 1287 1288 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) { 1289 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed"); 1290 return false; 1291 } 1292 1293 break; 1294 } 1295 case QOMX_IndexConfigVideoLTRPeriod: 1296 { 1297 QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam = 1298 (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData; 1299 1300 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1301 if (!venc_set_ltrperiod(pParam->nFrames)) { 1302 DEBUG_PRINT_ERROR("Setting ltr period failed"); 1303 return OMX_ErrorUnsupportedSetting; 1304 } 1305 } else { 1306 DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRPeriod " 1307 "called on wrong port(%d)", pParam->nPortIndex); 1308 return OMX_ErrorBadPortIndex; 1309 } 1310 1311 break; 1312 } 1313 case QOMX_IndexConfigVideoLTRUse: 1314 { 1315 QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = 1316 (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData; 1317 1318 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1319 if (!venc_set_ltruse(pParam->nID, pParam->nFrames)) { 1320 DEBUG_PRINT_ERROR("Setting ltr use failed"); 1321 return OMX_ErrorUnsupportedSetting; 1322 } 1323 } else { 1324 DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRUse " 1325 "called on wrong port(%d)", pParam->nPortIndex); 1326 return OMX_ErrorBadPortIndex; 1327 } 1328 1329 break; 1330 } 1331 default: 1332 DEBUG_PRINT_ERROR("venc_set_config: Unsupported index = 0x%x", index); 1333 break; 1334 } 1335 1336 return true; 1337 } 1338 1339 unsigned venc_dev::venc_stop( void) 1340 { 1341 #ifdef MAX_RES_1080P 1342 pmem_free(); 1343 #endif 1344 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL); 1345 } 1346 1347 unsigned venc_dev::venc_pause(void) 1348 { 1349 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL); 1350 } 1351 1352 unsigned venc_dev::venc_resume(void) 1353 { 1354 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ; 1355 } 1356 1357 unsigned venc_dev::venc_start_done(void) 1358 { 1359 return 0; 1360 } 1361 1362 unsigned venc_dev::venc_set_message_thread_id(pthread_t) 1363 { 1364 return 0; 1365 } 1366 1367 unsigned venc_dev::venc_start(void) 1368 { 1369 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start", 1370 __func__); 1371 1372 if (!venc_set_profile_level(0, 0)) { 1373 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET", 1374 __func__); 1375 } else { 1376 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET", 1377 __func__, codec_profile.profile, profile_level.level); 1378 } 1379 1380 if (m_max_allowed_bitrate_check && 1381 !venc_max_allowed_bitrate_check(bitrate.target_bitrate)) { 1382 DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed"); 1383 return -1; 1384 } 1385 1386 venc_config_print(); 1387 1388 #ifdef MAX_RES_1080P 1389 1390 if ((codec_profile.profile == VEN_PROFILE_MPEG4_SP) || 1391 (codec_profile.profile == VEN_PROFILE_H264_BASELINE) || 1392 (codec_profile.profile == VEN_PROFILE_H263_BASELINE)) 1393 recon_buffers_count = MAX_RECON_BUFFERS - 2; 1394 else 1395 recon_buffers_count = MAX_RECON_BUFFERS; 1396 1397 if (ltrmode.ltr_mode == (unsigned long)QOMX_VIDEO_LTRMode_Auto) { 1398 recon_buffers_count = MAX_RECON_BUFFERS; 1399 DEBUG_PRINT_HIGH("ltr mode enabled, so set recon buffers " 1400 "count to %d", recon_buffers_count); 1401 } 1402 1403 if (!venc_allocate_recon_buffers()) 1404 return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); 1405 else { 1406 DEBUG_PRINT_ERROR("Failed in creating Recon buffers"); 1407 return -1; 1408 } 1409 1410 #else 1411 return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); 1412 #endif 1413 } 1414 1415 #ifdef MAX_RES_1080P 1416 OMX_U32 venc_dev::venc_allocate_recon_buffers() 1417 { 1418 OMX_U32 yuv_size; 1419 struct venc_ioctl_msg ioctl_msg; 1420 struct venc_recon_buff_size recon_buff_size; 1421 1422 recon_buff_size.width = ((m_sVenc_cfg.input_width + 15) / 16) * 16; 1423 recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16; 1424 1425 DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d", m_sVenc_cfg.input_width, 1426 m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height); 1427 1428 ioctl_msg.in = NULL; 1429 ioctl_msg.out = (void*)&recon_buff_size; 1430 1431 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0) { 1432 DEBUG_PRINT_ERROR("VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" , 1433 recon_buff_size.width, recon_buff_size.height); 1434 return OMX_ErrorInsufficientResources; 1435 } 1436 1437 DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d", 1438 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width, 1439 recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment, 1440 recon_buffers_count); 1441 1442 for (int i = 0; i < recon_buffers_count; i++) { 1443 if (pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i)) { 1444 DEBUG_PRINT_ERROR("Error returned in allocating recon buffers"); 1445 return -1; 1446 } 1447 } 1448 1449 return 0; 1450 } 1451 OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count) 1452 { 1453 OMX_U32 pmem_fd = -1; 1454 OMX_U32 width, height; 1455 void *buf_addr = NULL; 1456 struct venc_ioctl_msg ioctl_msg; 1457 struct venc_recon_addr recon_addr; 1458 int rc = 0; 1459 1460 #ifdef USE_ION 1461 recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY); 1462 1463 if (recon_buff[count].ion_device_fd < 0) { 1464 DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed"); 1465 return -1; 1466 } 1467 1468 recon_buff[count].alloc_data.len = size; 1469 #ifdef MAX_RES_720P 1470 recon_buff[count].alloc_data.ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID); 1471 #else 1472 recon_buff[count].alloc_data.ION_HEAP_MASK = (ION_HEAP(MEM_HEAP_ID) | 1473 ION_HEAP(ION_IOMMU_HEAP_ID)); 1474 #endif 1475 recon_buff[count].alloc_data.flags = ION_FLAG_CACHED; 1476 recon_buff[count].alloc_data.align = clip2(alignment); 1477 1478 if (recon_buff[count].alloc_data.align != 8192) 1479 recon_buff[count].alloc_data.align = 8192; 1480 1481 rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data); 1482 1483 if (rc || !recon_buff[count].alloc_data.handle) { 1484 DEBUG_PRINT_ERROR("ION ALLOC memory failed "); 1485 recon_buff[count].alloc_data.handle=NULL; 1486 return -1; 1487 } 1488 1489 recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle; 1490 rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd); 1491 1492 if (rc) { 1493 DEBUG_PRINT_ERROR("ION MAP failed "); 1494 recon_buff[count].ion_alloc_fd.fd =-1; 1495 recon_buff[count].ion_alloc_fd.fd =-1; 1496 return -1; 1497 } 1498 1499 pmem_fd = recon_buff[count].ion_alloc_fd.fd; 1500 #else 1501 struct pmem_allocation allocation; 1502 pmem_fd = open(MEM_DEVICE, O_RDWR); 1503 1504 if ((int)(pmem_fd) < 0) { 1505 DEBUG_PRINT_ERROR("Failed to get an pmem handle"); 1506 return -1; 1507 } 1508 1509 allocation.size = size; 1510 allocation.align = clip2(alignment); 1511 1512 if (allocation.align != 8192) 1513 allocation.align = 8192; 1514 1515 if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) { 1516 DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)", 1517 allocation.align, allocation.size); 1518 return -1; 1519 } 1520 1521 #endif 1522 buf_addr = mmap(NULL, size, 1523 PROT_READ | PROT_WRITE, 1524 MAP_SHARED, pmem_fd, 0); 1525 1526 if (buf_addr == (void*) MAP_FAILED) { 1527 close(pmem_fd); 1528 pmem_fd = -1; 1529 DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p",buf_addr); 1530 #ifdef USE_ION 1531 1532 if (ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE, 1533 &recon_buff[count].alloc_data.handle)) { 1534 DEBUG_PRINT_LOW("ion recon buffer free failed"); 1535 } 1536 1537 recon_buff[count].alloc_data.handle = NULL; 1538 recon_buff[count].ion_alloc_fd.fd =-1; 1539 close(recon_buff[count].ion_device_fd); 1540 recon_buff[count].ion_device_fd =-1; 1541 #endif 1542 return -1; 1543 } 1544 1545 DEBUG_PRINT_HIGH("Allocated virt:%p, FD: %d of size %d", buf_addr, pmem_fd, size); 1546 1547 recon_addr.buffer_size = size; 1548 recon_addr.pmem_fd = pmem_fd; 1549 recon_addr.offset = 0; 1550 recon_addr.pbuffer = (unsigned char *)buf_addr; 1551 1552 ioctl_msg.in = (void*)&recon_addr; 1553 ioctl_msg.out = NULL; 1554 1555 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0) { 1556 DEBUG_PRINT_ERROR("Failed to set the Recon_buffers"); 1557 return -1; 1558 } 1559 1560 recon_buff[count].virtual_address = (unsigned char *) buf_addr; 1561 recon_buff[count].size = size; 1562 recon_buff[count].offset = 0; 1563 recon_buff[count].pmem_fd = pmem_fd; 1564 1565 DEBUG_PRINT_ERROR("Allocated virt:%p, FD: %d of size %d at index: %d", recon_buff[count].virtual_address, 1566 recon_buff[count].pmem_fd, recon_buff[count].size, count); 1567 return 0; 1568 } 1569 1570 OMX_U32 venc_dev::pmem_free() 1571 { 1572 int cnt = 0; 1573 struct venc_ioctl_msg ioctl_msg; 1574 struct venc_recon_addr recon_addr; 1575 1576 for (cnt = 0; cnt < recon_buffers_count; cnt++) { 1577 if (recon_buff[cnt].pmem_fd) { 1578 recon_addr.pbuffer = recon_buff[cnt].virtual_address; 1579 recon_addr.offset = recon_buff[cnt].offset; 1580 recon_addr.pmem_fd = recon_buff[cnt].pmem_fd; 1581 recon_addr.buffer_size = recon_buff[cnt].size; 1582 ioctl_msg.in = (void*)&recon_addr; 1583 ioctl_msg.out = NULL; 1584 1585 if (ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0) 1586 DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed"); 1587 1588 munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size); 1589 close(recon_buff[cnt].pmem_fd); 1590 #ifdef USE_ION 1591 1592 if (ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE, 1593 &recon_buff[cnt].alloc_data.handle)) { 1594 DEBUG_PRINT_LOW("ion recon buffer free failed"); 1595 } 1596 1597 recon_buff[cnt].alloc_data.handle = NULL; 1598 recon_buff[cnt].ion_alloc_fd.fd =-1; 1599 close(recon_buff[cnt].ion_device_fd); 1600 recon_buff[cnt].ion_device_fd =-1; 1601 #endif 1602 DEBUG_PRINT_LOW("cleaning Index %d of size %d",cnt,recon_buff[cnt].size); 1603 recon_buff[cnt].pmem_fd = -1; 1604 recon_buff[cnt].virtual_address = NULL; 1605 recon_buff[cnt].offset = 0; 1606 recon_buff[cnt].alignment = 0; 1607 recon_buff[cnt].size = 0; 1608 } 1609 } 1610 1611 return 0; 1612 } 1613 #endif 1614 1615 void venc_dev::venc_config_print() 1616 { 1617 1618 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %d, Profile %d, level : %d", 1619 m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); 1620 1621 DEBUG_PRINT_HIGH("ENC_CONFIG: Width: %d, Height:%d, Fps: %d", 1622 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, 1623 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); 1624 1625 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d", 1626 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); 1627 1628 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %d, qpP: %d, qpb: 0", 1629 session_qp.iframeqp, session_qp.pframqp); 1630 1631 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %d, maxQP: %d", 1632 qp_range.minqp, qp_range.maxqp); 1633 1634 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d", 1635 voptimecfg.voptime_resolution, multislice.mslice_mode, 1636 multislice.mslice_size); 1637 1638 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %d", 1639 entropy.longentropysel, entropy.cabacmodel); 1640 1641 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d", 1642 dbkfilter.db_mode, dbkfilter.slicealpha_offset, 1643 dbkfilter.slicebeta_offset); 1644 1645 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %d, HEC: %d", 1646 intra_refresh.mbcount, hec.header_extension); 1647 } 1648 1649 unsigned venc_dev::venc_flush( unsigned port) 1650 { 1651 struct venc_ioctl_msg ioctl_msg; 1652 struct venc_bufferflush buffer_index; 1653 1654 if (port == PORT_INDEX_IN) { 1655 DEBUG_PRINT_HIGH("Calling Input Flush"); 1656 buffer_index.flush_mode = VEN_FLUSH_INPUT; 1657 ioctl_msg.in = (void*)&buffer_index; 1658 ioctl_msg.out = NULL; 1659 1660 return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); 1661 } else if (port == PORT_INDEX_OUT) { 1662 DEBUG_PRINT_HIGH("Calling Output Flush"); 1663 buffer_index.flush_mode = VEN_FLUSH_OUTPUT; 1664 ioctl_msg.in = (void*)&buffer_index; 1665 ioctl_msg.out = NULL; 1666 return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); 1667 } else { 1668 return -1; 1669 } 1670 } 1671 1672 //allocating I/P memory from pmem and register with the device 1673 1674 1675 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned) 1676 { 1677 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1678 struct pmem *pmem_tmp; 1679 struct venc_bufferpayload dev_buffer = {0}; 1680 struct venc_allocatorproperty buff_alloc_property = {0}; 1681 1682 pmem_tmp = (struct pmem *)buf_addr; 1683 1684 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp); 1685 1686 if (port == PORT_INDEX_IN) { 1687 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 1688 dev_buffer.fd = pmem_tmp->fd; 1689 dev_buffer.maped_size = pmem_tmp->size; 1690 dev_buffer.sz = pmem_tmp->size; 1691 dev_buffer.offset = pmem_tmp->offset; 1692 1693 if ((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0)) { 1694 unsigned long ht = m_sVenc_cfg.input_height; 1695 unsigned long wd = m_sVenc_cfg.input_width; 1696 unsigned int luma_size, luma_size_2k; 1697 1698 ht = (ht + 15) & ~15; 1699 wd = (wd + 15) & ~15; 1700 1701 luma_size = ht * wd; 1702 luma_size_2k = (luma_size + 2047) & ~2047; 1703 1704 dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047); 1705 #ifdef USE_ION 1706 ioctl_msg.in = NULL; 1707 ioctl_msg.out = (void*)&buff_alloc_property; 1708 1709 if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { 1710 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:get input buffer failed "); 1711 return false; 1712 } 1713 1714 if (buff_alloc_property.alignment < 4096) { 1715 dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095); 1716 } else { 1717 dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) & 1718 ~(buff_alloc_property.alignment - 1)); 1719 } 1720 1721 #endif 1722 dev_buffer.maped_size = dev_buffer.sz; 1723 } 1724 1725 ioctl_msg.in = (void*)&dev_buffer; 1726 ioctl_msg.out = NULL; 1727 1728 DEBUG_PRINT_LOW("venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 1729 dev_buffer.pbuffer, \ 1730 dev_buffer.fd, \ 1731 dev_buffer.offset, \ 1732 dev_buffer.maped_size); 1733 1734 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0) { 1735 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:set input buffer failed "); 1736 return false; 1737 } 1738 } else if (port == PORT_INDEX_OUT) { 1739 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 1740 dev_buffer.fd = pmem_tmp->fd; 1741 dev_buffer.sz = pmem_tmp->size; 1742 dev_buffer.maped_size = pmem_tmp->size; 1743 dev_buffer.offset = pmem_tmp->offset; 1744 ioctl_msg.in = (void*)&dev_buffer; 1745 ioctl_msg.out = NULL; 1746 1747 DEBUG_PRINT_LOW("venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 1748 dev_buffer.pbuffer, \ 1749 dev_buffer.fd, \ 1750 dev_buffer.offset, \ 1751 dev_buffer.maped_size); 1752 1753 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0) { 1754 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:set output buffer failed "); 1755 return false; 1756 } 1757 } else { 1758 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index "); 1759 return false; 1760 } 1761 1762 return true; 1763 } 1764 1765 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) 1766 { 1767 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1768 struct pmem *pmem_tmp; 1769 struct venc_bufferpayload dev_buffer = {0}; 1770 1771 pmem_tmp = (struct pmem *)buf_addr; 1772 1773 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp); 1774 1775 if (port == PORT_INDEX_IN) { 1776 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 1777 dev_buffer.fd = pmem_tmp->fd; 1778 dev_buffer.maped_size = pmem_tmp->size; 1779 dev_buffer.sz = pmem_tmp->size; 1780 dev_buffer.offset = pmem_tmp->offset; 1781 ioctl_msg.in = (void*)&dev_buffer; 1782 ioctl_msg.out = NULL; 1783 1784 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 1785 dev_buffer.pbuffer, \ 1786 dev_buffer.fd, \ 1787 dev_buffer.offset, \ 1788 dev_buffer.maped_size); 1789 1790 if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0) { 1791 DEBUG_PRINT_ERROR("ERROR: venc_free_buf: free input buffer failed "); 1792 return false; 1793 } 1794 } else if (port == PORT_INDEX_OUT) { 1795 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 1796 dev_buffer.fd = pmem_tmp->fd; 1797 dev_buffer.sz = pmem_tmp->size; 1798 dev_buffer.maped_size = pmem_tmp->size; 1799 dev_buffer.offset = pmem_tmp->offset; 1800 ioctl_msg.in = (void*)&dev_buffer; 1801 ioctl_msg.out = NULL; 1802 1803 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 1804 dev_buffer.pbuffer, \ 1805 dev_buffer.fd, \ 1806 dev_buffer.offset, \ 1807 dev_buffer.maped_size); 1808 1809 if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0) { 1810 DEBUG_PRINT_ERROR("ERROR: venc_free_buf: free output buffer failed "); 1811 return false; 1812 } 1813 } else { 1814 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index "); 1815 return false; 1816 } 1817 1818 return true; 1819 } 1820 1821 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer, 1822 OMX_U32 width, OMX_U32 height) 1823 { 1824 DEBUG_PRINT_ERROR("%s not implemented!", __func__); 1825 return OMX_ErrorUnsupportedSetting; 1826 } 1827 1828 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned) 1829 { 1830 struct venc_buffer frameinfo; 1831 struct pmem *temp_buffer; 1832 struct venc_ioctl_msg ioctl_msg; 1833 struct OMX_BUFFERHEADERTYPE *bufhdr; 1834 1835 if (buffer == NULL) { 1836 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL"); 1837 return false; 1838 } 1839 1840 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 1841 1842 DEBUG_PRINT_LOW("Input buffer length %d",bufhdr->nFilledLen); 1843 1844 if (pmem_data_buf) { 1845 DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 1846 frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; 1847 } else { 1848 DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 1849 frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; 1850 } 1851 1852 frameinfo.clientdata = (void *) buffer; 1853 frameinfo.sz = bufhdr->nFilledLen; 1854 frameinfo.len = bufhdr->nFilledLen; 1855 frameinfo.flags = bufhdr->nFlags; 1856 frameinfo.offset = bufhdr->nOffset; 1857 frameinfo.timestamp = bufhdr->nTimeStamp; 1858 DEBUG_PRINT_LOW("i/p TS = %u", (OMX_U32)frameinfo.timestamp); 1859 ioctl_msg.in = &frameinfo; 1860 ioctl_msg.out = NULL; 1861 1862 DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", 1863 bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); 1864 1865 if (ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) { 1866 /*Generate an async error and move to invalid state*/ 1867 return false; 1868 } 1869 1870 if (m_debug.in_buffer_log) { 1871 venc_input_log_buffers(bufhdr, pmem_data_bufr, frameinfo.len); 1872 } 1873 1874 return true; 1875 } 1876 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned) 1877 { 1878 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1879 struct pmem *temp_buffer = NULL; 1880 struct venc_buffer frameinfo; 1881 struct OMX_BUFFERHEADERTYPE *bufhdr; 1882 1883 if (buffer == NULL) { 1884 return false; 1885 } 1886 1887 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 1888 1889 if (pmem_data_buf) { 1890 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); 1891 frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; 1892 } else { 1893 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 1894 frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; 1895 } 1896 1897 frameinfo.clientdata = buffer; 1898 frameinfo.sz = bufhdr->nAllocLen; 1899 frameinfo.flags = bufhdr->nFlags; 1900 frameinfo.offset = bufhdr->nOffset; 1901 1902 ioctl_msg.in = &frameinfo; 1903 ioctl_msg.out = NULL; 1904 DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", 1905 bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); 1906 1907 if (ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) { 1908 DEBUG_PRINT_ERROR("ERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed"); 1909 return false; 1910 } 1911 1912 return true; 1913 } 1914 1915 bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable) 1916 { 1917 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1918 DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable); 1919 1920 if (multislice.mslice_mode == VEN_MSLICE_CNT_MB) { 1921 if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0) { 1922 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); 1923 return false; 1924 } 1925 } else { 1926 DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set " 1927 "slice delivery mode to the driver.", multislice.mslice_mode); 1928 } 1929 1930 return true; 1931 } 1932 1933 bool venc_dev::venc_set_plusptype(OMX_BOOL enable) 1934 { 1935 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1936 struct venc_plusptype plusptype = {0}; 1937 DEBUG_PRINT_LOW("Set plusptype: %d", enable); 1938 plusptype.plusptype_enable = enable; 1939 ioctl_msg.in = (void*)&plusptype; 1940 ioctl_msg.out = NULL; 1941 1942 if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_H263_PLUSPTYPE,(void*)&ioctl_msg) < 0) { 1943 DEBUG_PRINT_ERROR("Request for setting plusptype for h263 failed"); 1944 return false; 1945 } 1946 1947 return true; 1948 } 1949 1950 bool venc_dev::venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode) 1951 { 1952 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1953 venc_ltrmode ltr_mode; 1954 ltr_mode.ltr_mode = (unsigned long)mode; 1955 DEBUG_PRINT_HIGH("Set ltr mode: %d", mode); 1956 ioctl_msg.in = (void*)<r_mode; 1957 ioctl_msg.out = NULL; 1958 1959 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRMODE, (void*)&ioctl_msg) < 0) { 1960 DEBUG_PRINT_ERROR("ERROR: Setting ltrmode failed"); 1961 return false; 1962 } 1963 1964 ltrmode.ltr_mode = (unsigned long)mode; 1965 return true; 1966 } 1967 1968 bool venc_dev::venc_set_ltrcount(OMX_U32 count) 1969 { 1970 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1971 venc_ltrcount ltr_count; 1972 ltr_count.ltr_count = (unsigned long)count; 1973 DEBUG_PRINT_HIGH("Set ltr count: %d", count); 1974 ioctl_msg.in = (void*)<r_count; 1975 ioctl_msg.out = NULL; 1976 1977 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRCOUNT, (void*)&ioctl_msg) < 0) { 1978 DEBUG_PRINT_ERROR("ERROR: Setting ltrcount failed"); 1979 return false; 1980 } 1981 1982 ltrcount.ltr_count = (unsigned long)count; 1983 return true; 1984 } 1985 1986 bool venc_dev::venc_set_ltrperiod(OMX_U32 period) 1987 { 1988 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1989 venc_ltrperiod ltr_period; 1990 ltr_period.ltr_period = (unsigned long)period; 1991 DEBUG_PRINT_HIGH("Set ltr period: %d", period); 1992 ioctl_msg.in = (void*)<r_period; 1993 ioctl_msg.out = NULL; 1994 1995 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRPERIOD, (void*)&ioctl_msg) < 0) { 1996 DEBUG_PRINT_ERROR("ERROR: Setting ltrperiod failed"); 1997 return false; 1998 } 1999 2000 ltrperiod.ltr_period = (unsigned long)period; 2001 return true; 2002 } 2003 2004 bool venc_dev::venc_set_ltruse(OMX_U32 id, OMX_U32 frames) 2005 { 2006 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2007 venc_ltruse ltr_use; 2008 ltr_use.ltr_id = (unsigned long)id; 2009 ltr_use.ltr_frames = (unsigned long)frames; 2010 DEBUG_PRINT_HIGH("Set ltr use: id = %d, ltr_frames = %d", id, frames); 2011 ioctl_msg.in = (void*)<r_use; 2012 ioctl_msg.out = NULL; 2013 2014 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRUSE, (void*)&ioctl_msg) < 0) { 2015 DEBUG_PRINT_ERROR("ERROR: Setting ltruse failed"); 2016 return false; 2017 } 2018 2019 return true; 2020 } 2021 2022 bool venc_dev::venc_set_extradata(OMX_U32 extra_data) 2023 { 2024 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2025 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data); 2026 ioctl_msg.in = (void*)&extra_data; 2027 ioctl_msg.out = NULL; 2028 2029 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0) { 2030 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); 2031 return false; 2032 } 2033 2034 return true; 2035 } 2036 2037 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp) 2038 { 2039 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2040 struct venc_sessionqp qp = {0, 0}; 2041 DEBUG_PRINT_HIGH("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp, 2042 p_frame_qp); 2043 2044 qp.iframeqp = i_frame_qp; 2045 qp.pframqp = p_frame_qp; 2046 2047 ioctl_msg.in = (void*)&qp; 2048 ioctl_msg.out = NULL; 2049 2050 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0) { 2051 DEBUG_PRINT_ERROR("ERROR: Request for setting session qp failed"); 2052 return false; 2053 } 2054 2055 session_qp.iframeqp = i_frame_qp; 2056 session_qp.pframqp = p_frame_qp; 2057 2058 return true; 2059 } 2060 2061 bool venc_dev::venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp) 2062 { 2063 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2064 struct venc_qprange qp = {0, 0}; 2065 DEBUG_PRINT_LOW("venc_set_qp_range:: min_qp = %d, max_qp = %d", min_qp, 2066 max_qp); 2067 2068 qp.minqp = min_qp; 2069 qp.maxqp = max_qp; 2070 2071 ioctl_msg.in = (void*)&qp; 2072 ioctl_msg.out = NULL; 2073 2074 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_QP_RANGE,(void*)&ioctl_msg)< 0) { 2075 DEBUG_PRINT_ERROR("ERROR: Request for setting qp range failed"); 2076 return false; 2077 } 2078 2079 qp_range.minqp= min_qp; 2080 qp_range.maxqp= max_qp; 2081 2082 return true; 2083 } 2084 2085 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) 2086 { 2087 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2088 struct venc_profile requested_profile; 2089 struct ven_profilelevel requested_level; 2090 unsigned const int *profile_tbl = NULL; 2091 unsigned long mb_per_frame = 0, mb_per_sec = 0; 2092 DEBUG_PRINT_HIGH("venc_set_profile_level:: eProfile = %d, Level = %d", 2093 eProfile, eLevel); 2094 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* 2095 ((m_sVenc_cfg.input_width + 15) >> 4); 2096 2097 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) { 2098 DEBUG_PRINT_HIGH("Set profile/level was done already"); 2099 return true; 2100 } 2101 2102 if (eProfile && eLevel) { 2103 /* non-zero values will be set by user, saving the same*/ 2104 m_eProfile = eProfile; 2105 m_eLevel = eLevel; 2106 DEBUG_PRINT_HIGH("Save profile/level (%d/%d) for max allowed bitrate check", 2107 m_eProfile, m_eLevel); 2108 } 2109 2110 DEBUG_PRINT_LOW("Validating Profile/Level from table"); 2111 2112 if (!venc_validate_profile_level(&eProfile, &eLevel)) { 2113 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed"); 2114 return false; 2115 } 2116 2117 if (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) { 2118 DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " 2119 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, 2120 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); 2121 2122 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 2123 requested_profile.profile = VEN_PROFILE_MPEG4_SP; 2124 profile_tbl = (unsigned int const *) 2125 (&mpeg4_profile_level_table[MPEG4_SP_START]); 2126 profile_tbl += MPEG4_720P_LEVEL*5; 2127 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 2128 requested_profile.profile = VEN_PROFILE_MPEG4_ASP; 2129 profile_tbl = (unsigned int const *) 2130 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 2131 profile_tbl += MPEG4_720P_LEVEL*5; 2132 } else { 2133 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u", 2134 eProfile); 2135 return false; 2136 } 2137 2138 DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," 2139 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," 2140 "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, 2141 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); 2142 2143 if (mb_per_frame >= 3600) { 2144 if (requested_profile.profile == VEN_PROFILE_MPEG4_ASP) 2145 requested_level.level = VEN_LEVEL_MPEG4_5; 2146 2147 if (requested_profile.profile == VEN_PROFILE_MPEG4_SP) 2148 requested_level.level = VEN_LEVEL_MPEG4_6; 2149 } else { 2150 switch (eLevel) { 2151 case OMX_VIDEO_MPEG4Level0: 2152 requested_level.level = VEN_LEVEL_MPEG4_0; 2153 break; 2154 case OMX_VIDEO_MPEG4Level1: 2155 requested_level.level = VEN_LEVEL_MPEG4_1; 2156 break; 2157 case OMX_VIDEO_MPEG4Level2: 2158 requested_level.level = VEN_LEVEL_MPEG4_2; 2159 break; 2160 case OMX_VIDEO_MPEG4Level3: 2161 requested_level.level = VEN_LEVEL_MPEG4_3; 2162 break; 2163 case OMX_VIDEO_MPEG4Level4a: 2164 requested_level.level = VEN_LEVEL_MPEG4_4; 2165 break; 2166 case OMX_VIDEO_MPEG4Level5: 2167 mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den); 2168 2169 if ((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) && 2170 (mb_per_sec >= profile_tbl[1])) { 2171 DEBUG_PRINT_LOW("MPEG4 Level 6 is set for 720p resolution"); 2172 requested_level.level = VEN_LEVEL_MPEG4_6; 2173 } else { 2174 DEBUG_PRINT_LOW("MPEG4 Level 5 is set for non-720p resolution"); 2175 requested_level.level = VEN_LEVEL_MPEG4_5; 2176 } 2177 2178 break; 2179 default: 2180 return false; 2181 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 2182 break; 2183 } 2184 } 2185 } else if (m_sVenc_cfg.codectype == VEN_CODEC_H263) { 2186 if (eProfile == OMX_VIDEO_H263ProfileBaseline) { 2187 requested_profile.profile = VEN_PROFILE_H263_BASELINE; 2188 } else { 2189 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %u", 2190 requested_profile.profile); 2191 return false; 2192 } 2193 2194 //profile level 2195 switch (eLevel) { 2196 case OMX_VIDEO_H263Level10: 2197 requested_level.level = VEN_LEVEL_H263_10; 2198 break; 2199 case OMX_VIDEO_H263Level20: 2200 requested_level.level = VEN_LEVEL_H263_20; 2201 break; 2202 case OMX_VIDEO_H263Level30: 2203 requested_level.level = VEN_LEVEL_H263_30; 2204 break; 2205 case OMX_VIDEO_H263Level40: 2206 requested_level.level = VEN_LEVEL_H263_40; 2207 break; 2208 case OMX_VIDEO_H263Level45: 2209 requested_level.level = VEN_LEVEL_H263_45; 2210 break; 2211 case OMX_VIDEO_H263Level50: 2212 requested_level.level = VEN_LEVEL_H263_50; 2213 break; 2214 case OMX_VIDEO_H263Level60: 2215 requested_level.level = VEN_LEVEL_H263_60; 2216 break; 2217 case OMX_VIDEO_H263Level70: 2218 requested_level.level = VEN_LEVEL_H263_70; 2219 break; 2220 default: 2221 return false; 2222 break; 2223 } 2224 } else if (m_sVenc_cfg.codectype == VEN_CODEC_H264) { 2225 if (eProfile == OMX_VIDEO_AVCProfileBaseline) { 2226 requested_profile.profile = VEN_PROFILE_H264_BASELINE; 2227 } else if (eProfile == OMX_VIDEO_AVCProfileMain) { 2228 requested_profile.profile = VEN_PROFILE_H264_MAIN; 2229 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) { 2230 requested_profile.profile = VEN_PROFILE_H264_HIGH; 2231 } else { 2232 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %u", 2233 requested_profile.profile); 2234 return false; 2235 } 2236 2237 //profile level 2238 switch (eLevel) { 2239 case OMX_VIDEO_AVCLevel1: 2240 requested_level.level = VEN_LEVEL_H264_1; 2241 break; 2242 case OMX_VIDEO_AVCLevel1b: 2243 requested_level.level = VEN_LEVEL_H264_1b; 2244 break; 2245 case OMX_VIDEO_AVCLevel11: 2246 requested_level.level = VEN_LEVEL_H264_1p1; 2247 break; 2248 case OMX_VIDEO_AVCLevel12: 2249 requested_level.level = VEN_LEVEL_H264_1p2; 2250 break; 2251 case OMX_VIDEO_AVCLevel13: 2252 requested_level.level = VEN_LEVEL_H264_1p3; 2253 break; 2254 case OMX_VIDEO_AVCLevel2: 2255 requested_level.level = VEN_LEVEL_H264_2; 2256 break; 2257 case OMX_VIDEO_AVCLevel21: 2258 requested_level.level = VEN_LEVEL_H264_2p1; 2259 break; 2260 case OMX_VIDEO_AVCLevel22: 2261 requested_level.level = VEN_LEVEL_H264_2p2; 2262 break; 2263 case OMX_VIDEO_AVCLevel3: 2264 requested_level.level = VEN_LEVEL_H264_3; 2265 break; 2266 case OMX_VIDEO_AVCLevel31: 2267 requested_level.level = VEN_LEVEL_H264_3p1; 2268 break; 2269 case OMX_VIDEO_AVCLevel32: 2270 requested_level.level = VEN_LEVEL_H264_3p2; 2271 break; 2272 case OMX_VIDEO_AVCLevel4: 2273 requested_level.level = VEN_LEVEL_H264_4; 2274 break; 2275 default : 2276 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %u", 2277 requested_level.level); 2278 return false; 2279 break; 2280 } 2281 } 2282 2283 if (!m_profile_set) { 2284 ioctl_msg.in = (void*)&requested_profile; 2285 ioctl_msg.out = NULL; 2286 2287 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0) { 2288 DEBUG_PRINT_ERROR("ERROR: Request for setting profile failed"); 2289 return false; 2290 } 2291 2292 codec_profile.profile = requested_profile.profile; 2293 m_profile_set = true; 2294 DEBUG_PRINT_HIGH("Set codec profile = 0x%x", codec_profile.profile); 2295 } 2296 2297 if (!m_level_set) { 2298 ioctl_msg.in = (void*)&requested_level; 2299 ioctl_msg.out = NULL; 2300 2301 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0) { 2302 DEBUG_PRINT_ERROR("ERROR: Request for setting profile level failed"); 2303 return false; 2304 } 2305 2306 profile_level.level = requested_level.level; 2307 m_level_set = true; 2308 DEBUG_PRINT_HIGH("Set codec level = 0x%x", profile_level.level); 2309 } 2310 2311 return true; 2312 } 2313 2314 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) 2315 { 2316 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2317 struct venc_voptimingcfg vop_timing_cfg; 2318 2319 DEBUG_PRINT_HIGH("venc_set_voptiming_cfg: TimeRes = %u", 2320 TimeIncRes); 2321 2322 vop_timing_cfg.voptime_resolution = TimeIncRes; 2323 2324 ioctl_msg.in = (void*)&vop_timing_cfg; 2325 ioctl_msg.out = NULL; 2326 2327 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0) { 2328 DEBUG_PRINT_ERROR("ERROR: Request for setting Vop Timing failed"); 2329 return false; 2330 } 2331 2332 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; 2333 return true; 2334 } 2335 2336 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) 2337 { 2338 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2339 struct venc_intraperiod intraperiod_cfg; 2340 2341 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u", 2342 nPFrames); 2343 intraperiod_cfg.num_pframes = nPFrames; 2344 2345 if ((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) || 2346 (codec_profile.profile == VEN_PROFILE_H264_MAIN) || 2347 (codec_profile.profile == VEN_PROFILE_H264_HIGH)) { 2348 #ifdef MAX_RES_1080P 2349 2350 if (nBFrames) { 2351 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); 2352 intraperiod_cfg.num_bframes = 1; 2353 } else 2354 intraperiod_cfg.num_bframes = 0; 2355 2356 #else 2357 2358 if (nBFrames) { 2359 DEBUG_PRINT_ERROR("B frames not supported"); 2360 intraperiod_cfg.num_bframes = 0; 2361 } else { 2362 DEBUG_PRINT_ERROR("B frames not supported"); 2363 intraperiod_cfg.num_bframes = 0; 2364 } 2365 2366 #endif 2367 } else 2368 intraperiod_cfg.num_bframes = 0; 2369 2370 DEBUG_PRINT_HIGH("venc_set_intra_period: nPFrames = %u nBFrames = %u", 2371 intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes); 2372 ioctl_msg.in = (void*)&intraperiod_cfg; 2373 ioctl_msg.out = NULL; 2374 2375 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0) { 2376 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 2377 return false; 2378 } 2379 2380 intra_period.num_pframes = intraperiod_cfg.num_pframes; 2381 intra_period.num_bframes = intraperiod_cfg.num_bframes; 2382 return true; 2383 } 2384 2385 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) 2386 { 2387 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2388 struct venc_entropycfg entropy_cfg; 2389 2390 memset(&entropy_cfg,0,sizeof(entropy_cfg)); 2391 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level); 2392 2393 if (enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)) { 2394 entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC; 2395 2396 if (i_cabac_level == 0) { 2397 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0; 2398 } 2399 2400 #ifdef MAX_RES_1080P 2401 else { 2402 DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to model 0",i_cabac_level); 2403 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0; 2404 } 2405 2406 #else 2407 else if (i_cabac_level == 1) { 2408 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1; 2409 } else if (i_cabac_level == 2) { 2410 entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2; 2411 } 2412 2413 #endif 2414 } else if (!enable) { 2415 entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC; 2416 } else { 2417 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile"); 2418 return false; 2419 } 2420 2421 ioctl_msg.in = (void*)&entropy_cfg; 2422 ioctl_msg.out = NULL; 2423 2424 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0) { 2425 DEBUG_PRINT_ERROR("ERROR: Request for setting entropy config failed"); 2426 return false; 2427 } 2428 2429 entropy.longentropysel = entropy_cfg.longentropysel; 2430 entropy.cabacmodel = entropy_cfg.cabacmodel; 2431 return true; 2432 } 2433 2434 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB 2435 { 2436 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 2437 bool status = true; 2438 struct venc_multiclicecfg multislice_cfg; 2439 2440 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) { 2441 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB; 2442 multislice_cfg.mslice_size = nSlicesize; 2443 } else { 2444 multislice_cfg.mslice_mode = VEN_MSLICE_OFF; 2445 multislice_cfg.mslice_size = 0; 2446 } 2447 2448 DEBUG_PRINT_LOW("%s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, 2449 multislice_cfg.mslice_size); 2450 2451 ioctl_msg.in = (void*)&multislice_cfg; 2452 ioctl_msg.out = NULL; 2453 2454 if (ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) { 2455 DEBUG_PRINT_ERROR("ERROR: Request for setting multi-slice cfg failed"); 2456 status = false; 2457 } else { 2458 multislice.mslice_mode = multislice_cfg.mslice_mode; 2459 multislice.mslice_size = nSlicesize; 2460 } 2461 2462 return status; 2463 } 2464 2465 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) 2466 { 2467 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 2468 bool status = true; 2469 struct venc_intrarefresh intraRefresh_cfg; 2470 2471 // There is no disabled mode. Disabled mode is indicated by a 0 count. 2472 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) { 2473 intraRefresh_cfg.irmode = VEN_IR_OFF; 2474 intraRefresh_cfg.mbcount = 0; 2475 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && 2476 (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) { 2477 intraRefresh_cfg.irmode = VEN_IR_CYCLIC; 2478 intraRefresh_cfg.mbcount = irMBs; 2479 } else { 2480 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:" 2481 "mb count: %d, mb mode:%d", irMBs, ir_mode); 2482 return false; 2483 } 2484 2485 ioctl_msg.in = (void*)&intraRefresh_cfg; 2486 ioctl_msg.out = NULL; 2487 2488 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0) { 2489 DEBUG_PRINT_ERROR("ERROR: Request for setting Intra Refresh failed"); 2490 status = false; 2491 } else { 2492 intra_refresh.irmode = intraRefresh_cfg.irmode; 2493 intra_refresh.mbcount = intraRefresh_cfg.mbcount; 2494 } 2495 2496 return status; 2497 } 2498 2499 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) 2500 { 2501 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 2502 bool status = true; 2503 struct venc_headerextension hec_cfg; 2504 struct venc_multiclicecfg multislice_cfg; 2505 2506 if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) { 2507 if (error_resilience->bEnableHEC) { 2508 hec_cfg.header_extension = 1; 2509 } else { 2510 hec_cfg.header_extension = 0; 2511 } 2512 2513 ioctl_msg.in = (void*)&hec_cfg; 2514 ioctl_msg.out = NULL; 2515 2516 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) { 2517 DEBUG_PRINT_ERROR("ERROR: Request for setting HEader Error correction failed"); 2518 return false; 2519 } 2520 2521 hec.header_extension = error_resilience->bEnableHEC; 2522 } 2523 2524 if (error_resilience->bEnableRVLC) { 2525 DEBUG_PRINT_ERROR("RVLC is not Supported"); 2526 return false; 2527 } 2528 2529 if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) && 2530 (error_resilience->bEnableDataPartitioning)) { 2531 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264"); 2532 return false; 2533 } 2534 2535 if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) && 2536 (error_resilience->nResynchMarkerSpacing)) { 2537 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; 2538 multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; 2539 } else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 && 2540 error_resilience->bEnableDataPartitioning) { 2541 multislice_cfg.mslice_mode = VEN_MSLICE_GOB; 2542 multislice_cfg.mslice_size = 0; 2543 } else { 2544 multislice_cfg.mslice_mode = VEN_MSLICE_OFF; 2545 multislice_cfg.mslice_size = 0; 2546 } 2547 2548 DEBUG_PRINT_LOW("%s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, 2549 multislice_cfg.mslice_size); 2550 ioctl_msg.in = (void*)&multislice_cfg; 2551 ioctl_msg.out = NULL; 2552 2553 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) { 2554 DEBUG_PRINT_ERROR("ERROR: Request for setting multi-slice cfg failed"); 2555 status = false; 2556 } else { 2557 multislice.mslice_mode = multislice_cfg.mslice_mode ; 2558 multislice.mslice_size = multislice_cfg.mslice_size; 2559 2560 } 2561 2562 return status; 2563 } 2564 2565 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) 2566 { 2567 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2568 struct venc_dbcfg filter_cfg; 2569 2570 memset(&filter_cfg, 0, sizeof(filter_cfg)); 2571 DEBUG_PRINT_LOW("venc_set_inloop_filter: %u",loopfilter); 2572 2573 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) { 2574 filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY; 2575 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) { 2576 filter_cfg.db_mode = VEN_DB_DISABLE; 2577 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) { 2578 filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY; 2579 } 2580 2581 filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0; 2582 2583 ioctl_msg.in = (void*)&filter_cfg; 2584 ioctl_msg.out = NULL; 2585 2586 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0) { 2587 DEBUG_PRINT_ERROR("ERROR: Request for setting inloop filter failed"); 2588 return false; 2589 } 2590 2591 dbkfilter.db_mode = filter_cfg.db_mode; 2592 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; 2593 return true; 2594 } 2595 2596 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) 2597 { 2598 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 2599 struct venc_targetbitrate bitrate_cfg; 2600 2601 DEBUG_PRINT_HIGH("venc_set_target_bitrate: bitrate = %u", 2602 nTargetBitrate); 2603 bitrate_cfg.target_bitrate = nTargetBitrate ; 2604 ioctl_msg.in = (void*)&bitrate_cfg; 2605 ioctl_msg.out = NULL; 2606 2607 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0) { 2608 DEBUG_PRINT_ERROR("ERROR: Request for setting bit rate failed"); 2609 return false; 2610 } 2611 2612 m_sVenc_cfg.targetbitrate = nTargetBitrate; 2613 bitrate.target_bitrate = nTargetBitrate; 2614 2615 if (!config) { 2616 m_level_set = false; 2617 2618 if (venc_set_profile_level(0, 0)) { 2619 DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d",profile_level.level); 2620 } 2621 } 2622 2623 return true; 2624 } 2625 2626 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) 2627 { 2628 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 2629 struct venc_framerate frame_rate_cfg; 2630 2631 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); 2632 2633 DEBUG_PRINT_HIGH("venc_set_encode_framerate: framerate(Q16) = %u, NR: %d, DR: %d", 2634 encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); 2635 2636 ioctl_msg.in = (void*)&frame_rate_cfg; 2637 ioctl_msg.out = NULL; 2638 2639 if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE, 2640 (void*)&ioctl_msg) < 0) { 2641 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed"); 2642 return false; 2643 } 2644 2645 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; 2646 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; 2647 2648 if (!config) { 2649 m_level_set = false; 2650 2651 if (venc_set_profile_level(0, 0)) { 2652 DEBUG_PRINT_LOW("Calling set level (Framerate) with %d",profile_level.level); 2653 } 2654 } 2655 2656 return true; 2657 } 2658 2659 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) 2660 { 2661 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 2662 2663 if (color_format == OMX_COLOR_FormatYUV420SemiPlanar) { 2664 #ifdef MAX_RES_1080P 2665 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; 2666 #else 2667 m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; 2668 #endif 2669 } else { 2670 DEBUG_PRINT_ERROR("WARNING: Unsupported Color format [%d]", color_format); 2671 #ifdef MAX_RES_1080P 2672 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; 2673 #else 2674 m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; 2675 #endif 2676 DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set"); 2677 } 2678 2679 ioctl_msg.in = (void*)&m_sVenc_cfg; 2680 ioctl_msg.out = NULL; 2681 2682 if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0) { 2683 DEBUG_PRINT_ERROR("ERROR: Request for setting color format failed"); 2684 return false; 2685 } 2686 2687 return true; 2688 } 2689 2690 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) 2691 { 2692 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); 2693 2694 if (intra_vop_refresh == OMX_TRUE) { 2695 if (ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0) { 2696 DEBUG_PRINT_ERROR("ERROR: Request for setting Intra VOP Refresh failed"); 2697 return false; 2698 } 2699 } else { 2700 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect"); 2701 } 2702 2703 return true; 2704 } 2705 2706 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) 2707 { 2708 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 2709 bool status = true; 2710 struct venc_ratectrlcfg ratectrl_cfg; 2711 2712 //rate control 2713 switch (eControlRate) { 2714 case OMX_Video_ControlRateDisable: 2715 ratectrl_cfg.rcmode = VEN_RC_OFF; 2716 break; 2717 case OMX_Video_ControlRateVariableSkipFrames: 2718 ratectrl_cfg.rcmode = VEN_RC_VBR_VFR; 2719 break; 2720 case OMX_Video_ControlRateVariable: 2721 ratectrl_cfg.rcmode = VEN_RC_VBR_CFR; 2722 break; 2723 case OMX_Video_ControlRateConstantSkipFrames: 2724 ratectrl_cfg.rcmode = VEN_RC_CBR_VFR; 2725 break; 2726 case OMX_Video_ControlRateConstant: 2727 ratectrl_cfg.rcmode = VEN_RC_CBR_CFR; 2728 break; 2729 default: 2730 status = false; 2731 break; 2732 } 2733 2734 if (status) { 2735 ioctl_msg.in = (void*)&ratectrl_cfg; 2736 ioctl_msg.out = NULL; 2737 2738 if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0) { 2739 DEBUG_PRINT_ERROR("ERROR: Request for setting rate control failed"); 2740 status = false; 2741 } else 2742 rate_ctrl.rcmode = ratectrl_cfg.rcmode; 2743 } 2744 2745 return status; 2746 } 2747 2748 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) 2749 { 2750 bool status = true; 2751 2752 if (eProfile == NULL || eLevel == NULL) { 2753 return false; 2754 } 2755 2756 if (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) { 2757 switch (codec_profile.profile) { 2758 case VEN_PROFILE_MPEG4_SP: 2759 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 2760 break; 2761 case VEN_PROFILE_MPEG4_ASP: 2762 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 2763 break; 2764 default: 2765 *eProfile = OMX_VIDEO_MPEG4ProfileMax; 2766 status = false; 2767 break; 2768 } 2769 2770 if (!status) { 2771 return status; 2772 } 2773 2774 //profile level 2775 switch (profile_level.level) { 2776 case VEN_LEVEL_MPEG4_0: 2777 *eLevel = OMX_VIDEO_MPEG4Level0; 2778 break; 2779 case VEN_LEVEL_MPEG4_1: 2780 *eLevel = OMX_VIDEO_MPEG4Level1; 2781 break; 2782 case VEN_LEVEL_MPEG4_2: 2783 *eLevel = OMX_VIDEO_MPEG4Level2; 2784 break; 2785 case VEN_LEVEL_MPEG4_3: 2786 *eLevel = OMX_VIDEO_MPEG4Level3; 2787 break; 2788 case VEN_LEVEL_MPEG4_4: 2789 *eLevel = OMX_VIDEO_MPEG4Level4a; 2790 break; 2791 case VEN_LEVEL_MPEG4_5: 2792 case VEN_LEVEL_MPEG4_6: 2793 *eLevel = OMX_VIDEO_MPEG4Level5; 2794 break; 2795 default: 2796 *eLevel = OMX_VIDEO_MPEG4LevelMax; 2797 status = false; 2798 break; 2799 } 2800 } else if (m_sVenc_cfg.codectype == VEN_CODEC_H263) { 2801 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) { 2802 *eProfile = OMX_VIDEO_H263ProfileBaseline; 2803 } else { 2804 *eProfile = OMX_VIDEO_H263ProfileMax; 2805 return false; 2806 } 2807 2808 switch (profile_level.level) { 2809 case VEN_LEVEL_H263_10: 2810 *eLevel = OMX_VIDEO_H263Level10; 2811 break; 2812 case VEN_LEVEL_H263_20: 2813 *eLevel = OMX_VIDEO_H263Level20; 2814 break; 2815 case VEN_LEVEL_H263_30: 2816 *eLevel = OMX_VIDEO_H263Level30; 2817 break; 2818 case VEN_LEVEL_H263_40: 2819 *eLevel = OMX_VIDEO_H263Level40; 2820 break; 2821 case VEN_LEVEL_H263_45: 2822 *eLevel = OMX_VIDEO_H263Level45; 2823 break; 2824 case VEN_LEVEL_H263_50: 2825 *eLevel = OMX_VIDEO_H263Level50; 2826 break; 2827 case VEN_LEVEL_H263_60: 2828 *eLevel = OMX_VIDEO_H263Level60; 2829 break; 2830 case VEN_LEVEL_H263_70: 2831 *eLevel = OMX_VIDEO_H263Level70; 2832 break; 2833 default: 2834 *eLevel = OMX_VIDEO_H263LevelMax; 2835 status = false; 2836 break; 2837 } 2838 } else if (m_sVenc_cfg.codectype == VEN_CODEC_H264) { 2839 switch (codec_profile.profile) { 2840 case VEN_PROFILE_H264_BASELINE: 2841 *eProfile = OMX_VIDEO_AVCProfileBaseline; 2842 break; 2843 case VEN_PROFILE_H264_MAIN: 2844 *eProfile = OMX_VIDEO_AVCProfileMain; 2845 break; 2846 case VEN_PROFILE_H264_HIGH: 2847 *eProfile = OMX_VIDEO_AVCProfileHigh; 2848 break; 2849 default: 2850 *eProfile = OMX_VIDEO_AVCProfileMax; 2851 status = false; 2852 break; 2853 } 2854 2855 if (!status) { 2856 return status; 2857 } 2858 2859 switch (profile_level.level) { 2860 case VEN_LEVEL_H264_1: 2861 *eLevel = OMX_VIDEO_AVCLevel1; 2862 break; 2863 case VEN_LEVEL_H264_1b: 2864 *eLevel = OMX_VIDEO_AVCLevel1b; 2865 break; 2866 case VEN_LEVEL_H264_1p1: 2867 *eLevel = OMX_VIDEO_AVCLevel11; 2868 break; 2869 case VEN_LEVEL_H264_1p2: 2870 *eLevel = OMX_VIDEO_AVCLevel12; 2871 break; 2872 case VEN_LEVEL_H264_1p3: 2873 *eLevel = OMX_VIDEO_AVCLevel13; 2874 break; 2875 case VEN_LEVEL_H264_2: 2876 *eLevel = OMX_VIDEO_AVCLevel2; 2877 break; 2878 case VEN_LEVEL_H264_2p1: 2879 *eLevel = OMX_VIDEO_AVCLevel21; 2880 break; 2881 case VEN_LEVEL_H264_2p2: 2882 *eLevel = OMX_VIDEO_AVCLevel22; 2883 break; 2884 case VEN_LEVEL_H264_3: 2885 *eLevel = OMX_VIDEO_AVCLevel3; 2886 break; 2887 case VEN_LEVEL_H264_3p1: 2888 *eLevel = OMX_VIDEO_AVCLevel31; 2889 break; 2890 case VEN_LEVEL_H264_3p2: 2891 *eLevel = OMX_VIDEO_AVCLevel32; 2892 break; 2893 case VEN_LEVEL_H264_4: 2894 *eLevel = OMX_VIDEO_AVCLevel4; 2895 break; 2896 default : 2897 *eLevel = OMX_VIDEO_AVCLevelMax; 2898 status = false; 2899 break; 2900 } 2901 } 2902 2903 return status; 2904 } 2905 2906 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) 2907 { 2908 OMX_U32 new_profile = 0, new_level = 0; 2909 unsigned const int *profile_tbl = NULL; 2910 OMX_U32 mb_per_frame, mb_per_sec; 2911 bool profile_level_found = false; 2912 2913 DEBUG_PRINT_LOW("Init profile table for respective codec"); 2914 2915 //validate the ht,width,fps,bitrate and set the appropriate profile and level 2916 if (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) { 2917 if (*eProfile == 0) { 2918 if (!m_profile_set) { 2919 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 2920 } else { 2921 switch (codec_profile.profile) { 2922 case VEN_PROFILE_MPEG4_ASP: 2923 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 2924 break; 2925 case VEN_PROFILE_MPEG4_SP: 2926 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 2927 break; 2928 default: 2929 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 2930 return false; 2931 } 2932 } 2933 } 2934 2935 if (*eLevel == 0 && !m_level_set) { 2936 *eLevel = OMX_VIDEO_MPEG4LevelMax; 2937 } 2938 2939 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 2940 profile_tbl = (unsigned int const *)mpeg4_profile_level_table; 2941 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 2942 profile_tbl = (unsigned int const *) 2943 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 2944 } else { 2945 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %lu", *eProfile); 2946 return false; 2947 } 2948 } else if (m_sVenc_cfg.codectype == VEN_CODEC_H264) { 2949 if (*eProfile == 0) { 2950 if (!m_profile_set) { 2951 *eProfile = OMX_VIDEO_AVCProfileBaseline; 2952 } else { 2953 switch (codec_profile.profile) { 2954 case VEN_PROFILE_H264_BASELINE: 2955 *eProfile = OMX_VIDEO_AVCProfileBaseline; 2956 break; 2957 case VEN_PROFILE_H264_MAIN: 2958 *eProfile = OMX_VIDEO_AVCProfileMain; 2959 break; 2960 case VEN_PROFILE_H264_HIGH: 2961 *eProfile = OMX_VIDEO_AVCProfileHigh; 2962 break; 2963 default: 2964 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 2965 return false; 2966 } 2967 } 2968 } 2969 2970 if (*eLevel == 0 && !m_level_set) { 2971 *eLevel = OMX_VIDEO_AVCLevelMax; 2972 } 2973 2974 if (*eProfile == OMX_VIDEO_AVCProfileBaseline) { 2975 profile_tbl = (unsigned int const *)h264_profile_level_table; 2976 } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) { 2977 profile_tbl = (unsigned int const *) 2978 (&h264_profile_level_table[H264_HP_START]); 2979 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) { 2980 profile_tbl = (unsigned int const *) 2981 (&h264_profile_level_table[H264_MP_START]); 2982 } else { 2983 DEBUG_PRINT_LOW("Unsupported AVC profile type %lu", *eProfile); 2984 return false; 2985 } 2986 } else if (m_sVenc_cfg.codectype == VEN_CODEC_H263) { 2987 if (*eProfile == 0) { 2988 if (!m_profile_set) { 2989 *eProfile = OMX_VIDEO_H263ProfileBaseline; 2990 } else { 2991 switch (codec_profile.profile) { 2992 case VEN_PROFILE_H263_BASELINE: 2993 *eProfile = OMX_VIDEO_H263ProfileBaseline; 2994 break; 2995 default: 2996 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 2997 return false; 2998 } 2999 } 3000 } 3001 3002 if (*eLevel == 0 && !m_level_set) { 3003 *eLevel = OMX_VIDEO_H263LevelMax; 3004 } 3005 3006 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) { 3007 profile_tbl = (unsigned int const *)h263_profile_level_table; 3008 } else { 3009 DEBUG_PRINT_LOW("Unsupported H.263 profile type %lu", *eProfile); 3010 return false; 3011 } 3012 } else { 3013 DEBUG_PRINT_LOW("Invalid codec type"); 3014 return false; 3015 } 3016 3017 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* 3018 ((m_sVenc_cfg.input_width + 15)>> 4); 3019 3020 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)) { 3021 if (codec_profile.profile == VEN_PROFILE_MPEG4_ASP) 3022 profile_level.level = VEN_LEVEL_MPEG4_5; 3023 3024 if (codec_profile.profile == VEN_PROFILE_MPEG4_SP) 3025 profile_level.level = VEN_LEVEL_MPEG4_6; 3026 3027 { 3028 new_level = profile_level.level; 3029 new_profile = codec_profile.profile; 3030 return true; 3031 } 3032 } 3033 3034 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; 3035 3036 do { 3037 if (mb_per_frame <= (int)profile_tbl[0]) { 3038 if (mb_per_sec <= (int)profile_tbl[1]) { 3039 if (m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2]) { 3040 new_level = (int)profile_tbl[3]; 3041 new_profile = (int)profile_tbl[4]; 3042 profile_level_found = true; 3043 DEBUG_PRINT_LOW("Appropriate profile/level found %d/%d", new_profile, new_level); 3044 break; 3045 } 3046 } 3047 } 3048 3049 profile_tbl = profile_tbl + 5; 3050 } while (profile_tbl[0] != 0); 3051 3052 if (profile_level_found != true) { 3053 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level"); 3054 return false; 3055 } 3056 3057 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) 3058 || (*eLevel == OMX_VIDEO_H263LevelMax)) { 3059 *eLevel = new_level; 3060 } 3061 3062 DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu" 3063 "Level = %lu", __func__, *eProfile, *eLevel); 3064 3065 return true; 3066 } 3067 3068 bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate) 3069 { 3070 unsigned const int *profile_tbl = NULL; 3071 3072 switch (m_sVenc_cfg.codectype) { 3073 case VEN_CODEC_MPEG4: 3074 3075 if (m_eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 3076 profile_tbl = (unsigned int const *)mpeg4_profile_level_table; 3077 } else if (m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 3078 profile_tbl = (unsigned int const *) 3079 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 3080 } else { 3081 DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile); 3082 return false; 3083 } 3084 3085 break; 3086 case VEN_CODEC_H264: 3087 3088 if (m_eProfile == OMX_VIDEO_AVCProfileBaseline) { 3089 profile_tbl = (unsigned int const *)h264_profile_level_table; 3090 } else if (m_eProfile == OMX_VIDEO_AVCProfileHigh) { 3091 profile_tbl = (unsigned int const *) 3092 (&h264_profile_level_table[H264_HP_START]); 3093 } else if (m_eProfile == OMX_VIDEO_AVCProfileMain) { 3094 profile_tbl = (unsigned int const *) 3095 (&h264_profile_level_table[H264_MP_START]); 3096 } else { 3097 DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile); 3098 return false; 3099 } 3100 3101 break; 3102 case VEN_CODEC_H263: 3103 3104 if (m_eProfile == OMX_VIDEO_H263ProfileBaseline) { 3105 profile_tbl = (unsigned int const *)h263_profile_level_table; 3106 } else { 3107 DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile); 3108 return false; 3109 } 3110 3111 break; 3112 default: 3113 DEBUG_PRINT_ERROR("%s: unknown codec type", __func__); 3114 return false; 3115 } 3116 3117 while (profile_tbl[0] != 0) { 3118 if (profile_tbl[3] == m_eLevel) { 3119 if (nTargetBitrate > profile_tbl[2]) { 3120 DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]" 3121 " is %u", m_eProfile, m_eLevel, profile_tbl[2]); 3122 return false; 3123 } 3124 } 3125 3126 profile_tbl += 5; 3127 } 3128 3129 return true; 3130 } 3131 3132 #ifdef _ANDROID_ICS_ 3133 bool venc_dev::venc_set_meta_mode(bool mode) 3134 { 3135 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 3136 ioctl_msg.in = &mode; 3137 DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode); 3138 3139 if (ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0) { 3140 DEBUG_PRINT_ERROR(" Set meta buffer mode failed"); 3141 return false; 3142 } 3143 3144 return true; 3145 } 3146 #endif 3147