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