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