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