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