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