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