1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010, Code Aurora Forum. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of Code Aurora nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 --------------------------------------------------------------------------*/ 28 #include<string.h> 29 #include <sys/ioctl.h> 30 #include<unistd.h> 31 #include <fcntl.h> 32 #include "video_encoder_device.h" 33 #include "omx_video_encoder.h" 34 35 #define MPEG4_SP_START 0 36 #define MPEG4_ASP_START (MPEG4_SP_START + 8) 37 #define MPEG4_720P_LEVEL 6 38 #define H263_BP_START 0 39 #define H264_BP_START 0 40 #define H264_HP_START (H264_BP_START + 11) 41 #define H264_MP_START (H264_BP_START + 21) 42 43 /* MPEG4 profile and level table*/ 44 static const unsigned int mpeg4_profile_level_table[][5]= 45 { 46 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 47 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, 48 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, 49 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, 50 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, 51 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, 52 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 53 {3600,108000,14000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 54 {0,0,0,0,0}, 55 56 {99,2970,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 57 {99,2970,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 58 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 59 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 60 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 61 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 62 {3600,108000,14000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 63 {0,0,0,0,0} 64 }; 65 66 /* H264 profile and level table*/ 67 static const unsigned int h264_profile_level_table[][5]= 68 { 69 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 70 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, 71 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, 72 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, 73 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, 74 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, 75 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, 76 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, 77 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, 78 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, 79 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, 80 {0,0,0,0,0}, 81 82 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, 83 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, 84 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, 85 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, 86 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, 87 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, 88 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, 89 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, 90 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, 91 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, 92 {0,0,0,0,0}, 93 94 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, 95 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, 96 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, 97 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, 98 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, 99 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, 100 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, 101 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, 102 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, 103 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, 104 {0,0,0,0,0} 105 }; 106 107 /* H263 profile and level table*/ 108 static const unsigned int h263_profile_level_table[][5]= 109 { 110 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 111 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, 112 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, 113 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, 114 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, 115 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, 116 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, 117 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, 118 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 119 {0,0,0,0,0} 120 }; 121 122 //constructor 123 venc_dev::venc_dev() 124 { 125 //nothing to do 126 127 } 128 129 venc_dev::~venc_dev() 130 { 131 //nothing to do 132 } 133 134 void* async_venc_message_thread (void *input) 135 { 136 struct venc_ioctl_msg ioctl_msg ={NULL,NULL}; 137 struct venc_timeout timeout; 138 struct venc_msg venc_msg; 139 omx_venc *omx = reinterpret_cast<omx_venc*>(input); 140 141 timeout.millisec = VEN_TIMEOUT_INFINITE; 142 while(1) 143 { 144 ioctl_msg.inputparam = NULL; 145 ioctl_msg.outputparam = (void*)&venc_msg; 146 147 /*Wait for a message from the video decoder driver*/ 148 if(ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg) < 0) 149 { 150 DEBUG_PRINT_ERROR("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed/stopped"); 151 break; 152 } 153 else 154 { 155 /*Call Instance specific process function*/ 156 if(omx->async_message_process(input,&venc_msg) < 0) 157 { 158 DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); 159 break; 160 } 161 } 162 } 163 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n"); 164 return NULL; 165 } 166 167 bool venc_dev::venc_open(OMX_U32 codec) 168 { 169 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 170 int r; 171 unsigned int alignment = 0,buffer_size = 0, temp =0; 172 173 m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); 174 if(m_nDriver_fd == 0) 175 { 176 DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n"); 177 m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); 178 } 179 180 if((int)m_nDriver_fd < 0) 181 { 182 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n"); 183 return false; 184 } 185 186 DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd); 187 // set the basic configuration of the video encoder driver 188 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; 189 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; 190 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; 191 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; 192 m_sVenc_cfg.fps_num = 30; 193 m_sVenc_cfg.fps_den = 1; 194 m_sVenc_cfg.targetbitrate = 64000; 195 m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12; 196 if(codec == OMX_VIDEO_CodingMPEG4) 197 { 198 m_sVenc_cfg.codectype = VEN_CODEC_MPEG4; 199 codec_profile.profile = VEN_PROFILE_MPEG4_SP; 200 profile_level.level = VEN_LEVEL_MPEG4_2; 201 } 202 else if(codec == OMX_VIDEO_CodingH263) 203 { 204 m_sVenc_cfg.codectype = VEN_CODEC_H263; 205 codec_profile.profile = VEN_PROFILE_H263_BASELINE; 206 profile_level.level = VEN_LEVEL_H263_20; 207 } 208 if(codec == OMX_VIDEO_CodingAVC) 209 { 210 m_sVenc_cfg.codectype = VEN_CODEC_H264; 211 codec_profile.profile = VEN_PROFILE_H264_BASELINE; 212 profile_level.level = VEN_LEVEL_H264_1p1; 213 } 214 ioctl_msg.inputparam = (void*)&m_sVenc_cfg; 215 ioctl_msg.outputparam = NULL; 216 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 ) 217 { 218 DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed"); 219 return false; 220 } 221 222 // Get the I/P and O/P buffer requirements 223 ioctl_msg.inputparam = NULL; 224 ioctl_msg.outputparam = (void*)&m_sInput_buff_property; 225 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 226 { 227 DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed"); 228 return false; 229 } 230 ioctl_msg.inputparam = NULL; 231 ioctl_msg.outputparam = (void*)&m_sOutput_buff_property; 232 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 233 { 234 DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed"); 235 return false; 236 } 237 238 m_profile_set = false; 239 m_level_set = false; 240 if(venc_set_profile_level(0, 0)) 241 { 242 DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success", 243 __func__); 244 } 245 246 return true; 247 } 248 249 void venc_dev::venc_close() 250 { 251 DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd); 252 if((int)m_nDriver_fd >= 0) 253 { 254 DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG"); 255 (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG, 256 NULL); 257 DEBUG_PRINT_LOW("\nCalling close()\n"); 258 close(m_nDriver_fd); 259 m_nDriver_fd = -1; 260 } 261 } 262 263 bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, 264 unsigned long *actual_buff_count, 265 unsigned long *buff_size, 266 unsigned long port) 267 { 268 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 269 unsigned long temp_count = 0; 270 271 if(port == 0) 272 { 273 if(*actual_buff_count > m_sInput_buff_property.mincount) 274 { 275 temp_count = m_sInput_buff_property.actualcount; 276 m_sInput_buff_property.actualcount = *actual_buff_count; 277 ioctl_msg.inputparam = (void*)&m_sInput_buff_property; 278 ioctl_msg.outputparam = NULL; 279 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 280 { 281 DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed"); 282 m_sInput_buff_property.actualcount = temp_count; 283 return false; 284 } 285 DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count); 286 } 287 } 288 else 289 { 290 if(*actual_buff_count > m_sOutput_buff_property.mincount) 291 { 292 temp_count = m_sOutput_buff_property.actualcount; 293 m_sOutput_buff_property.actualcount = *actual_buff_count; 294 ioctl_msg.inputparam = (void*)&m_sOutput_buff_property; 295 ioctl_msg.outputparam = NULL; 296 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 297 { 298 DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed"); 299 m_sOutput_buff_property.actualcount = temp_count; 300 return false; 301 } 302 DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count); 303 } 304 } 305 306 return true; 307 308 } 309 310 bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, 311 unsigned long *actual_buff_count, 312 unsigned long *buff_size, 313 unsigned long port) 314 { 315 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 316 317 if(port == 0) 318 { 319 ioctl_msg.inputparam = NULL; 320 ioctl_msg.outputparam = (void*)&m_sInput_buff_property; 321 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 322 { 323 DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed"); 324 return false; 325 } 326 *min_buff_count = m_sInput_buff_property.mincount; 327 *actual_buff_count = m_sInput_buff_property.actualcount; 328 *buff_size = m_sInput_buff_property.datasize 329 + (m_sInput_buff_property.datasize % m_sInput_buff_property.alignment) ; 330 } 331 else 332 { 333 ioctl_msg.inputparam = NULL; 334 ioctl_msg.outputparam = (void*)&m_sOutput_buff_property; 335 if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 336 { 337 DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed"); 338 return false; 339 } 340 *min_buff_count = m_sOutput_buff_property.mincount; 341 *actual_buff_count = m_sOutput_buff_property.actualcount; 342 *buff_size = m_sOutput_buff_property.datasize 343 + (m_sOutput_buff_property.datasize % m_sOutput_buff_property.alignment) ; 344 } 345 346 return true; 347 348 } 349 350 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) 351 { 352 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 353 OMX_U32 temp_out_buf_count = 0; 354 DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n"); 355 switch(index) 356 { 357 case OMX_IndexParamPortDefinition: 358 { 359 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 360 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 361 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n"); 362 if(portDefn->nPortIndex == PORT_INDEX_IN) 363 { 364 if(!venc_set_color_format(portDefn->format.video.eColorFormat)) 365 { 366 return false; 367 } 368 if(m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight || 369 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) 370 { 371 DEBUG_PRINT_LOW("\n Basic parameter has changed"); 372 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; 373 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; 374 375 temp_out_buf_count = m_sOutput_buff_property.actualcount; 376 ioctl_msg.inputparam = (void*)&m_sVenc_cfg; 377 ioctl_msg.outputparam = NULL; 378 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) 379 { 380 DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed"); 381 return false; 382 } 383 384 DEBUG_PRINT_LOW("\n Updating the buffer count/size for the new resolution"); 385 ioctl_msg.inputparam = NULL; 386 ioctl_msg.outputparam = (void*)&m_sInput_buff_property; 387 if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 388 { 389 DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed"); 390 return false; 391 } 392 DEBUG_PRINT_LOW("\n Got updated m_sInput_buff_property values: " 393 "datasize = %u, maxcount = %u, actualcnt = %u, " 394 "mincount = %u", m_sInput_buff_property.datasize, 395 m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount, 396 m_sInput_buff_property.mincount); 397 398 ioctl_msg.inputparam = NULL; 399 ioctl_msg.outputparam = (void*)&m_sOutput_buff_property; 400 if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 401 { 402 DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed"); 403 return false; 404 } 405 406 DEBUG_PRINT_LOW("\n Got updated m_sOutput_buff_property values: " 407 "datasize = %u, maxcount = %u, actualcnt = %u, " 408 "mincount = %u", m_sOutput_buff_property.datasize, 409 m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount, 410 m_sOutput_buff_property.mincount); 411 412 if(temp_out_buf_count < 7) 413 temp_out_buf_count = 7; 414 m_sOutput_buff_property.actualcount = temp_out_buf_count; 415 ioctl_msg.inputparam = (void*)&m_sOutput_buff_property; 416 ioctl_msg.outputparam = NULL; 417 if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 418 { 419 DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed"); 420 return false; 421 } 422 423 if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) && 424 (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) 425 { 426 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; 427 ioctl_msg.inputparam = (void*)&m_sInput_buff_property; 428 ioctl_msg.outputparam = NULL; 429 if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 430 { 431 DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed"); 432 return false; 433 } 434 } 435 if(m_sInput_buff_property.datasize != portDefn->nBufferSize) 436 { 437 DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u]," 438 "Driver's updated i/p bufsize = %u", portDefn->nBufferSize, 439 m_sInput_buff_property.datasize); 440 } 441 m_level_set = false; 442 if(venc_set_profile_level(0, 0)) 443 { 444 DEBUG_PRINT_HIGH("\n %s(): Dynamic Profile/Level setting success", 445 __func__); 446 } 447 } 448 else 449 { 450 if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) && 451 (m_sInput_buff_property.actualcount <= portDefn->nBufferCountActual) && 452 (m_sInput_buff_property.datasize == portDefn->nBufferSize)) 453 { 454 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; 455 ioctl_msg.inputparam = (void*)&m_sInput_buff_property; 456 ioctl_msg.outputparam = NULL; 457 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 458 { 459 DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_INPUT_BUFFER_REQ failed"); 460 return false; 461 } 462 } 463 else 464 { 465 DEBUG_PRINT_ERROR("\nERROR: Setting Input buffer requirements failed"); 466 return false; 467 } 468 } 469 } 470 else if(portDefn->nPortIndex == PORT_INDEX_OUT) 471 { 472 if(!venc_set_encode_framerate(portDefn->format.video.xFramerate)) 473 { 474 return false; 475 } 476 477 if(!venc_set_target_bitrate(portDefn->format.video.nBitrate)) 478 { 479 return false; 480 } 481 482 if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) 483 && 484 (m_sOutput_buff_property.actualcount <= portDefn->nBufferCountActual) 485 && 486 (m_sOutput_buff_property.datasize == portDefn->nBufferSize) 487 ) 488 { 489 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 490 ioctl_msg.inputparam = (void*)&m_sOutput_buff_property; 491 ioctl_msg.outputparam = NULL; 492 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) 493 { 494 DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed"); 495 return false; 496 } 497 } 498 else 499 { 500 DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed"); 501 return false; 502 } 503 } 504 else 505 { 506 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); 507 } 508 break; 509 } 510 case OMX_IndexParamVideoPortFormat: 511 { 512 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; 513 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 514 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n"); 515 516 if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) 517 { 518 if(!venc_set_color_format(portFmt->eColorFormat)) 519 { 520 return false; 521 } 522 } 523 else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 524 { 525 if(!venc_set_encode_framerate(portFmt->xFramerate)) 526 { 527 return false; 528 } 529 } 530 else 531 { 532 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); 533 } 534 break; 535 } 536 case OMX_IndexParamVideoBitrate: 537 { 538 OMX_VIDEO_PARAM_BITRATETYPE* pParam; 539 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 540 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n"); 541 542 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 543 { 544 if(!venc_set_target_bitrate(pParam->nTargetBitrate)) 545 { 546 DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed"); 547 return false; 548 } 549 if(!venc_set_ratectrl_cfg(pParam->eControlRate)) 550 { 551 DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed"); 552 return false; 553 } 554 } 555 else 556 { 557 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); 558 } 559 break; 560 } 561 case OMX_IndexParamVideoMpeg4: 562 { 563 OMX_VIDEO_PARAM_MPEG4TYPE* pParam; 564 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 565 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n"); 566 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 567 { 568 if(!venc_set_intra_period (pParam->nPFrames)) 569 { 570 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 571 return false; 572 } 573 574 m_profile_set = false; 575 m_level_set = false; 576 if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) 577 { 578 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); 579 return false; 580 } 581 } 582 else 583 { 584 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); 585 } 586 break; 587 } 588 case OMX_IndexParamVideoH263: 589 { 590 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 591 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n"); 592 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 593 { 594 if(venc_set_intra_period (pParam->nPFrames) == false) 595 { 596 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 597 return false; 598 } 599 600 m_profile_set = false; 601 m_level_set = false; 602 if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) 603 { 604 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); 605 return false; 606 } 607 } 608 else 609 { 610 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263"); 611 } 612 break; 613 } 614 case OMX_IndexParamVideoAvc: 615 { 616 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n"); 617 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 618 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 619 { 620 if(venc_set_intra_period (pParam->nPFrames) == false) 621 { 622 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 623 return false; 624 } 625 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n", 626 pParam->eProfile,pParam->eLevel); 627 628 m_profile_set = false; 629 m_level_set = false; 630 if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) 631 { 632 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); 633 return false; 634 } 635 } 636 else 637 { 638 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); 639 } 640 //TBD, lot of other variables to be updated, yet to decide 641 break; 642 } 643 case OMX_IndexParamVideoProfileLevelCurrent: 644 { 645 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n"); 646 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = 647 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 648 if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 649 { 650 m_profile_set = false; 651 m_level_set = false; 652 if(!venc_set_profile_level (profile_level->eProfile, 653 profile_level->eLevel)) 654 { 655 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); 656 return false; 657 } 658 } 659 else 660 { 661 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); 662 } 663 break; 664 } 665 case OMX_IndexParamVideoQuantization: 666 { 667 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n"); 668 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = 669 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; 670 if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 671 { 672 if(venc_set_session_qp (session_qp->nQpI, 673 session_qp->nQpP) == false) 674 { 675 DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed"); 676 return false; 677 } 678 } 679 else 680 { 681 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); 682 } 683 break; 684 } 685 case OMX_IndexParamVideoSliceFMO: 686 { 687 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoSliceFMO\n"); 688 OMX_VIDEO_PARAM_AVCSLICEFMO *avc_slice_fmo = 689 (OMX_VIDEO_PARAM_AVCSLICEFMO*)paramData; 690 DEBUG_PRINT_LOW("\n portindex = %u", avc_slice_fmo->nPortIndex); 691 if(avc_slice_fmo->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 692 { 693 if(venc_set_multislice_cfg(avc_slice_fmo->eSliceMode) == false) 694 { 695 DEBUG_PRINT_ERROR("\nERROR: Setting Multislice cfg failed"); 696 return false; 697 } 698 } 699 else 700 { 701 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for Multislice cfg"); 702 } 703 break; 704 } 705 default: 706 DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u", 707 index); 708 break; 709 //case 710 } 711 712 return true; 713 } 714 715 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) 716 { 717 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 718 DEBUG_PRINT_LOW("\n Inside venc_set_config"); 719 720 switch(index) 721 { 722 case OMX_IndexConfigVideoBitrate: 723 { 724 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) 725 configData; 726 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate"); 727 if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) 728 { 729 if(venc_set_target_bitrate(bit_rate->nEncodeBitrate) == false) 730 { 731 DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed"); 732 return false; 733 } 734 } 735 else 736 { 737 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); 738 } 739 break; 740 } 741 case OMX_IndexConfigVideoFramerate: 742 { 743 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) 744 configData; 745 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate"); 746 if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) 747 { 748 if(venc_set_encode_framerate(frame_rate->xEncodeFramerate) == false) 749 { 750 DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); 751 return false; 752 } 753 } 754 else 755 { 756 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 757 } 758 break; 759 } 760 case OMX_IndexConfigVideoIntraVOPRefresh: 761 { 762 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) 763 configData; 764 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); 765 if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) 766 { 767 if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) 768 { 769 DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); 770 return false; 771 } 772 } 773 else 774 { 775 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 776 } 777 break; 778 } 779 default: 780 DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index); 781 break; 782 } 783 784 return true; 785 } 786 787 unsigned venc_dev::venc_stop( void) 788 { 789 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL); 790 } 791 792 unsigned venc_dev::venc_pause(void) 793 { 794 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL); 795 } 796 797 unsigned venc_dev::venc_resume(void) 798 { 799 return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ; 800 } 801 802 unsigned venc_dev::venc_start(void) 803 { 804 DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start", 805 __func__); 806 if (!venc_set_profile_level(0, 0)) 807 { 808 DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET", 809 __func__); 810 } 811 else 812 { 813 DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET", 814 __func__, codec_profile.profile, profile_level.level); 815 } 816 817 return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); 818 } 819 820 unsigned venc_dev::venc_flush( unsigned port) 821 { 822 struct venc_ioctl_msg ioctl_msg; 823 struct venc_bufferflush buffer_index; 824 825 if(port == PORT_INDEX_IN) 826 { 827 buffer_index.flush_mode = VEN_FLUSH_INPUT; 828 ioctl_msg.inputparam = (void*)&buffer_index; 829 ioctl_msg.outputparam = NULL; 830 831 return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); 832 } 833 else if(port == PORT_INDEX_OUT) 834 { 835 buffer_index.flush_mode = VEN_FLUSH_OUTPUT; 836 ioctl_msg.inputparam = (void*)&buffer_index; 837 ioctl_msg.outputparam = NULL; 838 return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); 839 } 840 else 841 { 842 return -1; 843 } 844 } 845 846 //allocating I/P memory from pmem and register with the device 847 848 849 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port) 850 { 851 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 852 struct pmem *pmem_tmp; 853 struct venc_bufferpayload dev_buffer = {0}; 854 855 pmem_tmp = (struct pmem *)buf_addr; 856 857 DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); 858 859 if(port == PORT_INDEX_IN) 860 { 861 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 862 dev_buffer.fd = pmem_tmp->fd; 863 dev_buffer.maped_size = pmem_tmp->size; 864 dev_buffer.nsize = pmem_tmp->size; 865 dev_buffer.offset = pmem_tmp->offset; 866 ioctl_msg.inputparam = (void*)&dev_buffer; 867 ioctl_msg.outputparam = NULL; 868 869 DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 870 dev_buffer.pbuffer, \ 871 dev_buffer.fd, \ 872 dev_buffer.offset, \ 873 dev_buffer.maped_size); 874 875 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0) 876 { 877 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed "); 878 return false; 879 } 880 } 881 else if(port == PORT_INDEX_OUT) 882 { 883 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 884 dev_buffer.fd = pmem_tmp->fd; 885 dev_buffer.nsize = pmem_tmp->size; 886 dev_buffer.maped_size = pmem_tmp->size; 887 dev_buffer.offset = pmem_tmp->offset; 888 ioctl_msg.inputparam = (void*)&dev_buffer; 889 ioctl_msg.outputparam = NULL; 890 891 DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 892 dev_buffer.pbuffer, \ 893 dev_buffer.fd, \ 894 dev_buffer.offset, \ 895 dev_buffer.maped_size); 896 897 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0) 898 { 899 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed "); 900 return false; 901 } 902 } 903 else 904 { 905 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index "); 906 return false; 907 } 908 909 return true; 910 } 911 912 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) 913 { 914 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 915 struct pmem *pmem_tmp; 916 struct venc_bufferpayload dev_buffer = {0}; 917 918 pmem_tmp = (struct pmem *)buf_addr; 919 920 DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); 921 922 if(port == PORT_INDEX_IN) 923 { 924 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 925 dev_buffer.fd = pmem_tmp->fd; 926 dev_buffer.maped_size = pmem_tmp->size; 927 dev_buffer.nsize = pmem_tmp->size; 928 dev_buffer.offset = pmem_tmp->offset; 929 ioctl_msg.inputparam = (void*)&dev_buffer; 930 ioctl_msg.outputparam = NULL; 931 932 DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 933 dev_buffer.pbuffer, \ 934 dev_buffer.fd, \ 935 dev_buffer.offset, \ 936 dev_buffer.maped_size); 937 938 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0) 939 { 940 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed "); 941 return false; 942 } 943 } 944 else if(port == PORT_INDEX_OUT) 945 { 946 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 947 dev_buffer.fd = pmem_tmp->fd; 948 dev_buffer.nsize = pmem_tmp->size; 949 dev_buffer.maped_size = pmem_tmp->size; 950 dev_buffer.offset = pmem_tmp->offset; 951 ioctl_msg.inputparam = (void*)&dev_buffer; 952 ioctl_msg.outputparam = NULL; 953 954 DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 955 dev_buffer.pbuffer, \ 956 dev_buffer.fd, \ 957 dev_buffer.offset, \ 958 dev_buffer.maped_size); 959 960 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0) 961 { 962 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed "); 963 return false; 964 } 965 } 966 else 967 { 968 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index "); 969 return false; 970 } 971 972 return true; 973 } 974 975 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf) 976 { 977 struct venc_buffer frameinfo; 978 struct pmem *temp_buffer; 979 struct venc_ioctl_msg ioctl_msg; 980 struct OMX_BUFFERHEADERTYPE *bufhdr; 981 982 if(buffer == NULL) 983 { 984 DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL"); 985 return false; 986 } 987 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 988 989 DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen); 990 991 if(pmem_data_buf) 992 { 993 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 994 frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; 995 } 996 else 997 { 998 DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 999 frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; 1000 } 1001 1002 frameinfo.clientdata = (void *) buffer; 1003 frameinfo.size = bufhdr->nFilledLen; 1004 frameinfo.len = bufhdr->nFilledLen; 1005 frameinfo.flags = bufhdr->nFlags; 1006 frameinfo.offset = bufhdr->nOffset; 1007 frameinfo.timestamp = bufhdr->nTimeStamp; 1008 DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp); 1009 ioctl_msg.inputparam = &frameinfo; 1010 ioctl_msg.outputparam = NULL; 1011 1012 DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", 1013 bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); 1014 if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) 1015 { 1016 /*Generate an async error and move to invalid state*/ 1017 return false; 1018 } 1019 1020 return true; 1021 } 1022 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf) 1023 { 1024 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1025 struct pmem *temp_buffer = NULL; 1026 struct venc_buffer frameinfo; 1027 struct OMX_BUFFERHEADERTYPE *bufhdr; 1028 1029 if(buffer == NULL) 1030 { 1031 return false; 1032 } 1033 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 1034 1035 if(pmem_data_buf) 1036 { 1037 DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); 1038 frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; 1039 } 1040 else 1041 { 1042 DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 1043 frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; 1044 } 1045 1046 frameinfo.clientdata = buffer; 1047 frameinfo.size = bufhdr->nAllocLen; 1048 frameinfo.flags = bufhdr->nFlags; 1049 frameinfo.offset = bufhdr->nOffset; 1050 1051 ioctl_msg.inputparam = &frameinfo; 1052 ioctl_msg.outputparam = NULL; 1053 DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", 1054 bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); 1055 if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) 1056 { 1057 DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed"); 1058 return false; 1059 } 1060 1061 return true; 1062 } 1063 1064 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp) 1065 { 1066 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1067 struct venc_sessionqp qp = {0, 0}; 1068 DEBUG_PRINT_LOW("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp, 1069 p_frame_qp); 1070 1071 qp.iframeqp = i_frame_qp; 1072 qp.pframqp = p_frame_qp; 1073 1074 ioctl_msg.inputparam = (void*)&qp; 1075 ioctl_msg.outputparam = NULL; 1076 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0) 1077 { 1078 DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed"); 1079 return false; 1080 } 1081 1082 session_qp.iframeqp = i_frame_qp; 1083 session_qp.pframqp = p_frame_qp; 1084 1085 return true; 1086 } 1087 1088 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) 1089 { 1090 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1091 struct venc_profile requested_profile; 1092 struct ven_profilelevel requested_level; 1093 unsigned const int *profile_tbl = NULL; 1094 unsigned long mb_per_frame = 0, mb_per_sec = 0; 1095 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d", 1096 eProfile, eLevel); 1097 1098 if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) 1099 { 1100 DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start"); 1101 return true; 1102 } 1103 1104 DEBUG_PRINT_LOW("\n Validating Profile/Level from table"); 1105 if(!venc_validate_profile_level(&eProfile, &eLevel)) 1106 { 1107 DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed"); 1108 return false; 1109 } 1110 1111 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) 1112 { 1113 DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " 1114 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, 1115 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); 1116 if(eProfile == OMX_VIDEO_MPEG4ProfileSimple) 1117 { 1118 requested_profile.profile = VEN_PROFILE_MPEG4_SP; 1119 profile_tbl = (unsigned int const *) 1120 (&mpeg4_profile_level_table[MPEG4_SP_START]); 1121 profile_tbl += MPEG4_720P_LEVEL*5; 1122 } 1123 else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) 1124 { 1125 requested_profile.profile = VEN_PROFILE_MPEG4_ASP; 1126 profile_tbl = (unsigned int const *) 1127 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 1128 profile_tbl += MPEG4_720P_LEVEL*5; 1129 } 1130 else 1131 { 1132 DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u", 1133 eProfile); 1134 return false; 1135 } 1136 1137 DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," 1138 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," 1139 "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, 1140 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); 1141 1142 switch(eLevel) 1143 { 1144 case OMX_VIDEO_MPEG4Level0: 1145 requested_level.level = VEN_LEVEL_MPEG4_0; 1146 break; 1147 case OMX_VIDEO_MPEG4Level1: 1148 requested_level.level = VEN_LEVEL_MPEG4_1; 1149 break; 1150 case OMX_VIDEO_MPEG4Level2: 1151 requested_level.level = VEN_LEVEL_MPEG4_2; 1152 break; 1153 case OMX_VIDEO_MPEG4Level3: 1154 requested_level.level = VEN_LEVEL_MPEG4_3; 1155 break; 1156 case OMX_VIDEO_MPEG4Level4a: 1157 requested_level.level = VEN_LEVEL_MPEG4_4; 1158 break; 1159 case OMX_VIDEO_MPEG4Level5: 1160 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* 1161 ((m_sVenc_cfg.input_width + 15) >> 4); 1162 mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den); 1163 1164 if((mb_per_frame >= profile_tbl[0]) && 1165 (mb_per_sec >= profile_tbl[1])) 1166 { 1167 DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution"); 1168 requested_level.level = VEN_LEVEL_MPEG4_6; 1169 } 1170 else 1171 { 1172 DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution"); 1173 requested_level.level = VEN_LEVEL_MPEG4_5; 1174 } 1175 break; 1176 default: 1177 return false; 1178 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 1179 break; 1180 } 1181 } 1182 else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) 1183 { 1184 if(eProfile == OMX_VIDEO_H263ProfileBaseline) 1185 { 1186 requested_profile.profile = VEN_PROFILE_H263_BASELINE; 1187 } 1188 else 1189 { 1190 DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u", 1191 requested_profile.profile); 1192 return false; 1193 } 1194 //profile level 1195 switch(eLevel) 1196 { 1197 case OMX_VIDEO_H263Level10: 1198 requested_level.level = VEN_LEVEL_H263_10; 1199 break; 1200 case OMX_VIDEO_H263Level20: 1201 requested_level.level = VEN_LEVEL_H263_20; 1202 break; 1203 case OMX_VIDEO_H263Level30: 1204 requested_level.level = VEN_LEVEL_H263_30; 1205 break; 1206 case OMX_VIDEO_H263Level40: 1207 requested_level.level = VEN_LEVEL_H263_40; 1208 break; 1209 case OMX_VIDEO_H263Level45: 1210 requested_level.level = VEN_LEVEL_H263_45; 1211 break; 1212 case OMX_VIDEO_H263Level50: 1213 requested_level.level = VEN_LEVEL_H263_50; 1214 break; 1215 case OMX_VIDEO_H263Level60: 1216 requested_level.level = VEN_LEVEL_H263_60; 1217 break; 1218 case OMX_VIDEO_H263Level70: 1219 requested_level.level = VEN_LEVEL_H263_70; 1220 break; 1221 default: 1222 return false; 1223 break; 1224 } 1225 } 1226 else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) 1227 { 1228 if(eProfile == OMX_VIDEO_AVCProfileBaseline) 1229 { 1230 requested_profile.profile = VEN_PROFILE_H264_BASELINE; 1231 } 1232 else if(eProfile == OMX_VIDEO_AVCProfileMain) 1233 { 1234 requested_profile.profile = VEN_PROFILE_H264_MAIN; 1235 } 1236 else if(eProfile == OMX_VIDEO_AVCProfileHigh) 1237 { 1238 requested_profile.profile = VEN_PROFILE_H264_HIGH; 1239 } 1240 else 1241 { 1242 DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u", 1243 requested_profile.profile); 1244 return false; 1245 } 1246 //profile level 1247 switch(eLevel) 1248 { 1249 case OMX_VIDEO_AVCLevel1: 1250 requested_level.level = VEN_LEVEL_H264_1; 1251 break; 1252 case OMX_VIDEO_AVCLevel1b: 1253 requested_level.level = VEN_LEVEL_H264_1b; 1254 break; 1255 case OMX_VIDEO_AVCLevel11: 1256 requested_level.level = VEN_LEVEL_H264_1p1; 1257 break; 1258 case OMX_VIDEO_AVCLevel12: 1259 requested_level.level = VEN_LEVEL_H264_1p2; 1260 break; 1261 case OMX_VIDEO_AVCLevel13: 1262 requested_level.level = VEN_LEVEL_H264_1p3; 1263 break; 1264 case OMX_VIDEO_AVCLevel2: 1265 requested_level.level = VEN_LEVEL_H264_2; 1266 break; 1267 case OMX_VIDEO_AVCLevel21: 1268 requested_level.level = VEN_LEVEL_H264_2p1; 1269 break; 1270 case OMX_VIDEO_AVCLevel22: 1271 requested_level.level = VEN_LEVEL_H264_2p2; 1272 break; 1273 case OMX_VIDEO_AVCLevel3: 1274 requested_level.level = VEN_LEVEL_H264_3; 1275 break; 1276 case OMX_VIDEO_AVCLevel31: 1277 requested_level.level = VEN_LEVEL_H264_3p1; 1278 break; 1279 default : 1280 return false; 1281 break; 1282 } 1283 } 1284 1285 if(!m_profile_set) 1286 { 1287 ioctl_msg.inputparam = (void*)&requested_profile; 1288 ioctl_msg.outputparam = NULL; 1289 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0) 1290 { 1291 DEBUG_PRINT_LOW("\nERROR: Request for setting profile failed"); 1292 return false; 1293 } 1294 codec_profile.profile = requested_profile.profile; 1295 m_profile_set = true; 1296 } 1297 1298 if(!m_level_set) 1299 { 1300 ioctl_msg.inputparam = (void*)&requested_level; 1301 ioctl_msg.outputparam = NULL; 1302 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0) 1303 { 1304 DEBUG_PRINT_LOW("\nERROR: Request for setting profile level failed"); 1305 return false; 1306 } 1307 profile_level.level = requested_level.level; 1308 m_level_set = true; 1309 } 1310 1311 return true; 1312 } 1313 1314 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames) 1315 { 1316 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1317 struct venc_intraperiod intra_period; 1318 1319 DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u", 1320 nPFrames); 1321 intra_period.num_pframes = nPFrames; 1322 ioctl_msg.inputparam = (void*)&intra_period; 1323 ioctl_msg.outputparam = NULL; 1324 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0) 1325 { 1326 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 1327 return false; 1328 } 1329 1330 return true; 1331 } 1332 1333 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate) 1334 { 1335 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 1336 struct venc_targetbitrate bit_rate; 1337 1338 DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u", 1339 nTargetBitrate); 1340 bit_rate.target_bitrate = nTargetBitrate ; 1341 ioctl_msg.inputparam = (void*)&bit_rate; 1342 ioctl_msg.outputparam = NULL; 1343 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0) 1344 { 1345 DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed"); 1346 return false; 1347 } 1348 m_sVenc_cfg.targetbitrate = nTargetBitrate; 1349 m_level_set = false; 1350 if(venc_set_profile_level(0, 0)) 1351 { 1352 DEBUG_PRINT_HIGH("\n %s(): Dynamic Profile/Level setting success", 1353 __func__); 1354 } 1355 1356 return true; 1357 } 1358 1359 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate) 1360 { 1361 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 1362 struct venc_framerate frame_rate; 1363 1364 DEBUG_PRINT_LOW("\n venc_set_encode_framerate: framerate(Q16) = %u", 1365 encode_framerate); 1366 frame_rate.fps_numerator = 30; 1367 if((encode_framerate >> 16)== 30) 1368 { 1369 frame_rate.fps_denominator = 1; 1370 } 1371 else if((encode_framerate >>16) == 15) 1372 { 1373 frame_rate.fps_denominator = 2; 1374 } 1375 else if((encode_framerate >> 16)== 7.5) 1376 { 1377 frame_rate.fps_denominator = 4; 1378 } 1379 else 1380 { 1381 frame_rate.fps_denominator = 1; 1382 } 1383 1384 ioctl_msg.inputparam = (void*)&frame_rate; 1385 ioctl_msg.outputparam = NULL; 1386 if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE, 1387 (void*)&ioctl_msg) < 0) 1388 { 1389 DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed"); 1390 return false; 1391 } 1392 1393 m_sVenc_cfg.fps_den = frame_rate.fps_denominator; 1394 m_sVenc_cfg.fps_num = frame_rate.fps_numerator; 1395 m_level_set = false; 1396 if(venc_set_profile_level(0, 0)) 1397 { 1398 DEBUG_PRINT_HIGH("\n %s(): Dynamic Profile/Level setting success", 1399 __func__); 1400 } 1401 1402 return true; 1403 } 1404 1405 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) 1406 { 1407 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 1408 DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format); 1409 1410 if(color_format == OMX_COLOR_FormatYUV420SemiPlanar) 1411 { 1412 m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; 1413 } 1414 else 1415 { 1416 DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format); 1417 m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; 1418 DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set"); 1419 } 1420 ioctl_msg.inputparam = (void*)&m_sVenc_cfg; 1421 ioctl_msg.outputparam = NULL; 1422 if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0) 1423 { 1424 DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed"); 1425 return false; 1426 } 1427 return true; 1428 } 1429 1430 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) 1431 { 1432 DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); 1433 if(intra_vop_refresh == OMX_TRUE) 1434 { 1435 if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0) 1436 { 1437 DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed"); 1438 return false; 1439 } 1440 } 1441 else 1442 { 1443 DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect"); 1444 } 1445 return true; 1446 } 1447 1448 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) 1449 { 1450 venc_ioctl_msg ioctl_msg = {NULL,NULL}; 1451 bool status = true; 1452 1453 //rate control 1454 switch(eControlRate) 1455 { 1456 case OMX_Video_ControlRateDisable: 1457 rate_ctrl.rcmode = VEN_RC_OFF; 1458 break; 1459 case OMX_Video_ControlRateVariableSkipFrames: 1460 rate_ctrl.rcmode = VEN_RC_VBR_VFR; 1461 break; 1462 case OMX_Video_ControlRateVariable: 1463 rate_ctrl.rcmode = VEN_RC_VBR_CFR; 1464 break; 1465 case OMX_Video_ControlRateConstantSkipFrames: 1466 rate_ctrl.rcmode = VEN_RC_CBR_VFR; 1467 break; 1468 default: 1469 status = false; 1470 break; 1471 } 1472 1473 if(status) 1474 { 1475 ioctl_msg.inputparam = (void*)&rate_ctrl; 1476 ioctl_msg.outputparam = NULL; 1477 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0) 1478 { 1479 DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed"); 1480 status = false; 1481 } 1482 } 1483 return status; 1484 } 1485 1486 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) 1487 { 1488 bool status = true; 1489 if(eProfile == NULL || eLevel == NULL) 1490 { 1491 return false; 1492 } 1493 1494 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) 1495 { 1496 switch(codec_profile.profile) 1497 { 1498 case VEN_PROFILE_MPEG4_SP: 1499 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 1500 break; 1501 case VEN_PROFILE_MPEG4_ASP: 1502 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 1503 break; 1504 default: 1505 *eProfile = OMX_VIDEO_MPEG4ProfileMax; 1506 status = false; 1507 break; 1508 } 1509 1510 if(!status) 1511 { 1512 return status; 1513 } 1514 1515 //profile level 1516 switch(profile_level.level) 1517 { 1518 case VEN_LEVEL_MPEG4_0: 1519 *eLevel = OMX_VIDEO_MPEG4Level0; 1520 break; 1521 case VEN_LEVEL_MPEG4_1: 1522 *eLevel = OMX_VIDEO_MPEG4Level1; 1523 break; 1524 case VEN_LEVEL_MPEG4_2: 1525 *eLevel = OMX_VIDEO_MPEG4Level2; 1526 break; 1527 case VEN_LEVEL_MPEG4_3: 1528 *eLevel = OMX_VIDEO_MPEG4Level3; 1529 break; 1530 case VEN_LEVEL_MPEG4_4: 1531 *eLevel = OMX_VIDEO_MPEG4Level4a; 1532 break; 1533 case VEN_LEVEL_MPEG4_5: 1534 case VEN_LEVEL_MPEG4_6: 1535 *eLevel = OMX_VIDEO_MPEG4Level5; 1536 break; 1537 default: 1538 *eLevel = OMX_VIDEO_MPEG4LevelMax; 1539 status = false; 1540 break; 1541 } 1542 } 1543 else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) 1544 { 1545 if(codec_profile.profile == VEN_PROFILE_H263_BASELINE) 1546 { 1547 *eProfile = OMX_VIDEO_H263ProfileBaseline; 1548 } 1549 else 1550 { 1551 *eProfile = OMX_VIDEO_H263ProfileMax; 1552 return false; 1553 } 1554 switch(profile_level.level) 1555 { 1556 case VEN_LEVEL_H263_10: 1557 *eLevel = OMX_VIDEO_H263Level10; 1558 break; 1559 case VEN_LEVEL_H263_20: 1560 *eLevel = OMX_VIDEO_H263Level20; 1561 break; 1562 case VEN_LEVEL_H263_30: 1563 *eLevel = OMX_VIDEO_H263Level30; 1564 break; 1565 case VEN_LEVEL_H263_40: 1566 *eLevel = OMX_VIDEO_H263Level40; 1567 break; 1568 case VEN_LEVEL_H263_45: 1569 *eLevel = OMX_VIDEO_H263Level45; 1570 break; 1571 case VEN_LEVEL_H263_50: 1572 *eLevel = OMX_VIDEO_H263Level50; 1573 break; 1574 case VEN_LEVEL_H263_60: 1575 *eLevel = OMX_VIDEO_H263Level60; 1576 break; 1577 case VEN_LEVEL_H263_70: 1578 *eLevel = OMX_VIDEO_H263Level70; 1579 break; 1580 default: 1581 *eLevel = OMX_VIDEO_H263LevelMax; 1582 status = false; 1583 break; 1584 } 1585 } 1586 else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) 1587 { 1588 switch(codec_profile.profile) 1589 { 1590 case VEN_PROFILE_H264_BASELINE: 1591 *eProfile = OMX_VIDEO_AVCProfileBaseline; 1592 break; 1593 case VEN_PROFILE_H264_MAIN: 1594 *eProfile = OMX_VIDEO_AVCProfileMain; 1595 break; 1596 case VEN_PROFILE_H264_HIGH: 1597 *eProfile = OMX_VIDEO_AVCProfileHigh; 1598 break; 1599 default: 1600 *eProfile = OMX_VIDEO_AVCProfileMax; 1601 status = false; 1602 break; 1603 } 1604 1605 if(!status) 1606 { 1607 return status; 1608 } 1609 1610 switch(profile_level.level) 1611 { 1612 case VEN_LEVEL_H264_1: 1613 *eLevel = OMX_VIDEO_AVCLevel1; 1614 break; 1615 case VEN_LEVEL_H264_1b: 1616 *eLevel = OMX_VIDEO_AVCLevel1b; 1617 break; 1618 case VEN_LEVEL_H264_1p1: 1619 *eLevel = OMX_VIDEO_AVCLevel11; 1620 break; 1621 case VEN_LEVEL_H264_1p2: 1622 *eLevel = OMX_VIDEO_AVCLevel12; 1623 break; 1624 case VEN_LEVEL_H264_1p3: 1625 *eLevel = OMX_VIDEO_AVCLevel13; 1626 break; 1627 case VEN_LEVEL_H264_2: 1628 *eLevel = OMX_VIDEO_AVCLevel2; 1629 break; 1630 case VEN_LEVEL_H264_2p1: 1631 *eLevel = OMX_VIDEO_AVCLevel21; 1632 break; 1633 case VEN_LEVEL_H264_2p2: 1634 *eLevel = OMX_VIDEO_AVCLevel22; 1635 break; 1636 case VEN_LEVEL_H264_3: 1637 *eLevel = OMX_VIDEO_AVCLevel3; 1638 break; 1639 case VEN_LEVEL_H264_3p1: 1640 *eLevel = OMX_VIDEO_AVCLevel31; 1641 break; 1642 default : 1643 *eLevel = OMX_VIDEO_AVCLevelMax; 1644 status = false; 1645 break; 1646 } 1647 } 1648 return status; 1649 } 1650 1651 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) 1652 { 1653 OMX_U32 new_profile = 0, new_level = 0; 1654 unsigned const int *profile_tbl = NULL; 1655 OMX_U32 mb_per_frame, mb_per_sec; 1656 bool profile_level_found = false; 1657 1658 DEBUG_PRINT_LOW("\n Init profile table for respective codec"); 1659 //validate the ht,width,fps,bitrate and set the appropriate profile and level 1660 if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) 1661 { 1662 if(*eProfile == 0) 1663 { 1664 if(!m_profile_set) 1665 { 1666 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 1667 } 1668 else 1669 { 1670 switch(codec_profile.profile) 1671 { 1672 case VEN_PROFILE_MPEG4_ASP: 1673 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 1674 break; 1675 case VEN_PROFILE_MPEG4_SP: 1676 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 1677 break; 1678 default: 1679 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); 1680 return false; 1681 } 1682 } 1683 } 1684 1685 if(*eLevel == 0 && !m_level_set) 1686 { 1687 *eLevel = OMX_VIDEO_MPEG4LevelMax; 1688 } 1689 1690 if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple) 1691 { 1692 profile_tbl = (unsigned int const *)mpeg4_profile_level_table; 1693 } 1694 else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) 1695 { 1696 profile_tbl = (unsigned int const *) 1697 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 1698 } 1699 else 1700 { 1701 DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile); 1702 return false; 1703 } 1704 } 1705 else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) 1706 { 1707 if(*eProfile == 0) 1708 { 1709 if(!m_profile_set) 1710 { 1711 *eProfile = OMX_VIDEO_AVCProfileBaseline; 1712 } 1713 else 1714 { 1715 switch(codec_profile.profile) 1716 { 1717 case VEN_PROFILE_H264_BASELINE: 1718 *eProfile = OMX_VIDEO_AVCProfileBaseline; 1719 break; 1720 case VEN_PROFILE_H264_MAIN: 1721 *eProfile = OMX_VIDEO_AVCProfileMain; 1722 break; 1723 case VEN_PROFILE_H264_HIGH: 1724 *eProfile = OMX_VIDEO_AVCProfileHigh; 1725 break; 1726 default: 1727 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); 1728 return false; 1729 } 1730 } 1731 } 1732 1733 if(*eLevel == 0 && !m_level_set) 1734 { 1735 *eLevel = OMX_VIDEO_AVCLevelMax; 1736 } 1737 1738 if(*eProfile == OMX_VIDEO_AVCProfileBaseline) 1739 { 1740 profile_tbl = (unsigned int const *)h264_profile_level_table; 1741 } 1742 else if(*eProfile == OMX_VIDEO_AVCProfileHigh) 1743 { 1744 profile_tbl = (unsigned int const *) 1745 (&h264_profile_level_table[H264_HP_START]); 1746 } 1747 else if(*eProfile == OMX_VIDEO_AVCProfileMain) 1748 { 1749 profile_tbl = (unsigned int const *) 1750 (&h264_profile_level_table[H264_MP_START]); 1751 } 1752 else 1753 { 1754 DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile); 1755 return false; 1756 } 1757 } 1758 else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) 1759 { 1760 if(*eProfile == 0) 1761 { 1762 if(!m_profile_set) 1763 { 1764 *eProfile = OMX_VIDEO_H263ProfileBaseline; 1765 } 1766 else 1767 { 1768 switch(codec_profile.profile) 1769 { 1770 case VEN_PROFILE_H263_BASELINE: 1771 *eProfile = OMX_VIDEO_H263ProfileBaseline; 1772 break; 1773 default: 1774 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); 1775 return false; 1776 } 1777 } 1778 } 1779 1780 if(*eLevel == 0 && !m_level_set) 1781 { 1782 *eLevel = OMX_VIDEO_H263LevelMax; 1783 } 1784 1785 if(*eProfile == OMX_VIDEO_H263ProfileBaseline) 1786 { 1787 profile_tbl = (unsigned int const *)h263_profile_level_table; 1788 } 1789 else 1790 { 1791 DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile); 1792 return false; 1793 } 1794 } 1795 else 1796 { 1797 DEBUG_PRINT_LOW("\n Invalid codec type"); 1798 return false; 1799 } 1800 1801 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* 1802 ((m_sVenc_cfg.input_width + 15)>> 4); 1803 1804 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; 1805 1806 do{ 1807 if(mb_per_frame <= (int)profile_tbl[0]) 1808 { 1809 if(mb_per_sec <= (int)profile_tbl[1]) 1810 { 1811 if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2]) 1812 { 1813 DEBUG_PRINT_LOW("\n Appropriate profile/level found \n"); 1814 new_level = (int)profile_tbl[3]; 1815 new_profile = (int)profile_tbl[4]; 1816 profile_level_found = true; 1817 break; 1818 } 1819 } 1820 } 1821 profile_tbl = profile_tbl + 5; 1822 }while(profile_tbl[0] != 0); 1823 1824 if ((profile_level_found != true) || (new_profile != *eProfile) 1825 || (new_level > *eLevel)) 1826 { 1827 DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n"); 1828 return false; 1829 } 1830 1831 if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) 1832 || (*eLevel == OMX_VIDEO_H263LevelMax)) 1833 { 1834 *eLevel = new_level; 1835 } 1836 DEBUG_PRINT_HIGH("%s: Returning with eProfile = %lu" 1837 "Level = %lu", __func__, *eProfile, *eLevel); 1838 1839 return true; 1840 } 1841 bool venc_dev::venc_set_multislice_cfg(OMX_VIDEO_AVCSLICEMODETYPE eSliceMode) 1842 { 1843 venc_ioctl_msg ioctl_msg = {NULL, NULL}; 1844 bool status = true; 1845 DEBUG_PRINT_LOW("\n %s(): eSliceMode = %u", __func__, eSliceMode); 1846 switch(eSliceMode) 1847 { 1848 case OMX_VIDEO_SLICEMODE_AVCDefault: 1849 DEBUG_PRINT_LOW("\n %s(): OMX_VIDEO_SLICEMODE_AVCDefault", __func__); 1850 multislice_cfg.mslice_mode = VEN_MSLICE_OFF; 1851 multislice_cfg.mslice_size = 0; 1852 break; 1853 case OMX_VIDEO_SLICEMODE_AVCMBSlice: 1854 DEBUG_PRINT_LOW("\n %s(): OMX_VIDEO_SLICEMODE_AVCMBSlice", __func__); 1855 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB; 1856 multislice_cfg.mslice_size = ((m_sVenc_cfg.input_width/16) * 1857 (m_sVenc_cfg.input_height/16))/2; 1858 break; 1859 case OMX_VIDEO_SLICEMODE_AVCByteSlice: 1860 DEBUG_PRINT_LOW("\n %s(): OMX_VIDEO_SLICEMODE_AVCByteSlice", __func__); 1861 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; 1862 multislice_cfg.mslice_size = 1920; 1863 break; 1864 default: 1865 DEBUG_PRINT_ERROR("\n %s(): Unsupported SliceMode = %u",__func__, eSliceMode); 1866 status = false; 1867 break; 1868 } 1869 DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, 1870 multislice_cfg.mslice_size); 1871 1872 if(status) 1873 { 1874 ioctl_msg.inputparam = (void*)&multislice_cfg; 1875 ioctl_msg.outputparam = NULL; 1876 if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) 1877 { 1878 DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed"); 1879 status = false; 1880 } 1881 } 1882 return status; 1883 } 1884