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