1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of The Linux Foundation nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 --------------------------------------------------------------------------*/ 28 29 #include <string.h> 30 #include <sys/ioctl.h> 31 #include <sys/prctl.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include "video_encoder_device_v4l2.h" 35 #include "omx_video_encoder.h" 36 #include <linux/android_pmem.h> 37 #ifdef USE_ION 38 #include <linux/msm_ion.h> 39 #endif 40 #include <media/msm_media_info.h> 41 #include <cutils/properties.h> 42 43 #ifdef _ANDROID_ 44 #include <media/hardware/HardwareAPI.h> 45 #include <gralloc_priv.h> 46 #endif 47 48 #define EXTRADATA_IDX(__num_planes) (__num_planes - 1) 49 50 #define MPEG4_SP_START 0 51 #define MPEG4_ASP_START (MPEG4_SP_START + 10) 52 #define H263_BP_START 0 53 #define H264_BP_START 0 54 #define H264_HP_START (H264_BP_START + 17) 55 #define H264_MP_START (H264_BP_START + 34) 56 #define POLL_TIMEOUT 1000 57 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */ 58 59 /* MPEG4 profile and level table*/ 60 static const unsigned int mpeg4_profile_level_table[][5]= { 61 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 62 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, 63 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, 64 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, 65 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, 66 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, 67 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 68 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 69 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 70 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 71 {0,0,0,0,0}, 72 73 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 74 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 75 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 76 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 77 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 78 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 79 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 80 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 81 {0,0,0,0,0}, 82 }; 83 84 /* H264 profile and level table*/ 85 static const unsigned int h264_profile_level_table[][5]= { 86 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 87 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, 88 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, 89 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, 90 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, 91 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, 92 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, 93 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, 94 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, 95 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, 96 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, 97 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, 98 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, 99 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline}, 100 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline}, 101 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline}, 102 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline}, 103 {0,0,0,0,0}, 104 105 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, 106 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, 107 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, 108 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, 109 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, 110 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, 111 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, 112 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, 113 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, 114 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, 115 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, 116 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, 117 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh}, 118 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh}, 119 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh}, 120 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh}, 121 {0,0,0,0,0}, 122 123 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, 124 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, 125 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, 126 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, 127 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, 128 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, 129 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, 130 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, 131 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, 132 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, 133 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, 134 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, 135 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain}, 136 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain}, 137 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain}, 138 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain}, 139 {0,0,0,0,0} 140 141 }; 142 143 /* H263 profile and level table*/ 144 static const unsigned int h263_profile_level_table[][5]= { 145 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 146 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, 147 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, 148 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, 149 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, 150 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, 151 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, 152 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, 153 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 154 {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 155 {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 156 {0,0,0,0,0} 157 }; 158 159 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 160 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 161 162 #ifdef INPUT_BUFFER_LOG 163 FILE *inputBufferFile1; 164 char inputfilename [] = "/data/input.yuv"; 165 #endif 166 #ifdef OUTPUT_BUFFER_LOG 167 FILE *outputBufferFile1; 168 char outputfilename [] = "/data/output-bitstream.\0\0\0\0"; 169 #endif 170 171 //constructor 172 venc_dev::venc_dev(class omx_venc *venc_class) 173 { 174 //nothing to do 175 int i = 0; 176 venc_handle = venc_class; 177 etb = ebd = ftb = fbd = 0; 178 179 for (i = 0; i < MAX_PORT; i++) 180 streaming[i] = false; 181 182 stopped = 1; 183 paused = false; 184 async_thread_created = false; 185 color_format = 0; 186 pthread_mutex_init(&pause_resume_mlock, NULL); 187 pthread_cond_init(&pause_resume_cond, NULL); 188 memset(&extradata_info, 0, sizeof(extradata_info)); 189 memset(&idrperiod, 0, sizeof(idrperiod)); 190 memset(&multislice, 0, sizeof(multislice)); 191 memset (&slice_mode, 0 , sizeof(slice_mode)); 192 memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg)); 193 memset(&rate_ctrl, 0, sizeof(rate_ctrl)); 194 memset(&bitrate, 0, sizeof(bitrate)); 195 memset(&intra_period, 0, sizeof(intra_period)); 196 memset(&codec_profile, 0, sizeof(codec_profile)); 197 memset(&set_param, 0, sizeof(set_param)); 198 memset(&time_inc, 0, sizeof(time_inc)); 199 memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property)); 200 memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property)); 201 memset(&session_qp, 0, sizeof(session_qp)); 202 memset(&entropy, 0, sizeof(entropy)); 203 memset(&dbkfilter, 0, sizeof(dbkfilter)); 204 memset(&intra_refresh, 0, sizeof(intra_refresh)); 205 memset(&hec, 0, sizeof(hec)); 206 memset(&voptimecfg, 0, sizeof(voptimecfg)); 207 memset(&capability, 0, sizeof(capability)); 208 } 209 210 venc_dev::~venc_dev() 211 { 212 //nothing to do 213 } 214 215 void* venc_dev::async_venc_message_thread (void *input) 216 { 217 struct venc_msg venc_msg; 218 omx_video* omx_venc_base = NULL; 219 omx_venc *omx = reinterpret_cast<omx_venc*>(input); 220 omx_venc_base = reinterpret_cast<omx_video*>(input); 221 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 222 223 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); 224 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 225 struct pollfd pfd; 226 struct v4l2_buffer v4l2_buf; 227 struct v4l2_event dqevent; 228 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 229 pfd.fd = omx->handle->m_nDriver_fd; 230 int error_code = 0,rc=0; 231 232 memset(&v4l2_buf, 0, sizeof(v4l2_buf)); 233 234 while (1) { 235 pthread_mutex_lock(&omx->handle->pause_resume_mlock); 236 237 if (omx->handle->paused) { 238 venc_msg.msgcode = VEN_MSG_PAUSE; 239 venc_msg.statuscode = VEN_S_SUCCESS; 240 241 if (omx->async_message_process(input, &venc_msg) < 0) { 242 DEBUG_PRINT_ERROR("\nERROR: Failed to process pause msg"); 243 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 244 break; 245 } 246 247 /* Block here until the IL client resumes us again */ 248 pthread_cond_wait(&omx->handle->pause_resume_cond, 249 &omx->handle->pause_resume_mlock); 250 251 venc_msg.msgcode = VEN_MSG_RESUME; 252 venc_msg.statuscode = VEN_S_SUCCESS; 253 254 if (omx->async_message_process(input, &venc_msg) < 0) { 255 DEBUG_PRINT_ERROR("\nERROR: Failed to process resume msg"); 256 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 257 break; 258 } 259 } 260 261 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 262 263 rc = poll(&pfd, 1, POLL_TIMEOUT); 264 265 if (!rc) { 266 DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d\n", 267 omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd); 268 continue; 269 } else if (rc < 0) { 270 DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); 271 break; 272 } 273 274 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { 275 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 276 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 277 v4l2_buf.length = omx->handle->num_planes; 278 v4l2_buf.m.planes = plane; 279 280 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { 281 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE; 282 venc_msg.statuscode=VEN_S_SUCCESS; 283 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index; 284 venc_msg.buf.len= v4l2_buf.m.planes->bytesused; 285 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset; 286 venc_msg.buf.flags = 0; 287 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer; 288 venc_msg.buf.clientdata=(void*)omxhdr; 289 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec; 290 291 /* TODO: ideally report other types of frames as well 292 * for now it doesn't look like IL client cares about 293 * other types 294 */ 295 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) 296 venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR; 297 298 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) 299 venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME; 300 301 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG) 302 venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG; 303 304 if (v4l2_buf.flags & V4L2_BUF_FLAG_EOS) 305 venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS; 306 307 if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused) 308 venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA; 309 310 omx->handle->fbd++; 311 312 if (omx->async_message_process(input,&venc_msg) < 0) { 313 DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); 314 break; 315 } 316 } 317 } 318 319 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { 320 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 321 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 322 v4l2_buf.m.planes = plane; 323 v4l2_buf.length = 1; 324 325 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { 326 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE; 327 venc_msg.statuscode=VEN_S_SUCCESS; 328 omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index; 329 venc_msg.buf.clientdata=(void*)omxhdr; 330 omx->handle->ebd++; 331 332 if (omx->async_message_process(input,&venc_msg) < 0) { 333 DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); 334 break; 335 } 336 } 337 } 338 339 if (pfd.revents & POLLPRI) { 340 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); 341 342 if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { 343 DEBUG_PRINT_HIGH("CLOSE DONE\n"); 344 break; 345 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 346 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE; 347 venc_msg.statuscode = VEN_S_SUCCESS; 348 349 if (omx->async_message_process(input,&venc_msg) < 0) { 350 DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); 351 break; 352 } 353 354 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE; 355 venc_msg.statuscode = VEN_S_SUCCESS; 356 357 if (omx->async_message_process(input,&venc_msg) < 0) { 358 DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); 359 break; 360 } 361 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { 362 DEBUG_PRINT_ERROR("\n HW Error recieved \n"); 363 venc_msg.statuscode=VEN_S_EFAIL; 364 365 if (omx->async_message_process(input,&venc_msg) < 0) { 366 DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); 367 break; 368 } 369 } 370 } 371 } 372 373 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n"); 374 return NULL; 375 } 376 377 static const int event_type[] = { 378 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 379 V4L2_EVENT_MSM_VIDC_CLOSE_DONE, 380 V4L2_EVENT_MSM_VIDC_SYS_ERROR 381 }; 382 383 static OMX_ERRORTYPE subscribe_to_events(int fd) 384 { 385 OMX_ERRORTYPE eRet = OMX_ErrorNone; 386 struct v4l2_event_subscription sub; 387 int array_sz = sizeof(event_type)/sizeof(int); 388 int i,rc; 389 memset(&sub, 0, sizeof(sub)); 390 391 if (fd < 0) { 392 printf("Invalid input: %d\n", fd); 393 return OMX_ErrorBadParameter; 394 } 395 396 for (i = 0; i < array_sz; ++i) { 397 memset(&sub, 0, sizeof(sub)); 398 sub.type = event_type[i]; 399 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 400 401 if (rc) { 402 printf("Failed to subscribe event: 0x%x\n", sub.type); 403 break; 404 } 405 } 406 407 if (i < array_sz) { 408 for (--i; i >=0 ; i--) { 409 memset(&sub, 0, sizeof(sub)); 410 sub.type = event_type[i]; 411 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 412 413 if (rc) 414 printf("Failed to unsubscribe event: 0x%x\n", sub.type); 415 } 416 417 eRet = OMX_ErrorNotImplemented; 418 } 419 420 return eRet; 421 } 422 423 bool venc_dev::handle_extradata(void *buffer, int index) 424 { 425 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer; 426 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 427 428 if (!extradata_info.uaddr) { 429 DEBUG_PRINT_ERROR("Extradata buffers not allocated\n"); 430 return false; 431 } 432 433 p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(p_bufhdr->pBuffer + p_bufhdr->nOffset + p_bufhdr->nFilledLen + 3)&(~3)); 434 char *p_extradata = extradata_info.uaddr + index * extradata_info.buffer_size; 435 436 if ((OMX_U8*)p_extra > (p_bufhdr->pBuffer + p_bufhdr->nAllocLen)) { 437 DEBUG_PRINT_ERROR("Insufficient buffer size\n"); 438 p_extra = NULL; 439 return false; 440 } 441 442 memcpy(p_extra, p_extradata, extradata_info.buffer_size); 443 return true; 444 } 445 446 int venc_dev::venc_set_format(int format) 447 { 448 int rc = true; 449 450 if (format) 451 color_format = format; 452 else { 453 color_format = 0; 454 rc = false; 455 } 456 457 return rc; 458 } 459 460 OMX_ERRORTYPE venc_dev::allocate_extradata() 461 { 462 if (extradata_info.allocated) { 463 DEBUG_PRINT_ERROR("2nd allocation return"); 464 return OMX_ErrorNone; 465 } 466 467 #ifdef USE_ION 468 469 if (extradata_info.buffer_size) { 470 if (extradata_info.ion.ion_alloc_data.handle) { 471 munmap((void *)extradata_info.uaddr, extradata_info.size); 472 close(extradata_info.ion.fd_ion_data.fd); 473 free_ion_memory(&extradata_info.ion); 474 } 475 476 extradata_info.size = (extradata_info.size + 4095) & (~4095); 477 478 extradata_info.ion.ion_device_fd = alloc_map_ion_memory( 479 extradata_info.size, 480 &extradata_info.ion.ion_alloc_data, 481 &extradata_info.ion.fd_ion_data, 0); 482 483 if (extradata_info.ion.ion_device_fd < 0) { 484 DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); 485 return OMX_ErrorInsufficientResources; 486 } 487 488 extradata_info.uaddr = (char *)mmap(NULL, 489 extradata_info.size, 490 PROT_READ|PROT_WRITE, MAP_SHARED, 491 extradata_info.ion.fd_ion_data.fd , 0); 492 493 if (extradata_info.uaddr == MAP_FAILED) { 494 DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); 495 close(extradata_info.ion.fd_ion_data.fd); 496 free_ion_memory(&extradata_info.ion); 497 return OMX_ErrorInsufficientResources; 498 } 499 } 500 501 #endif 502 extradata_info.allocated = 1; 503 return OMX_ErrorNone; 504 } 505 506 void venc_dev::free_extradata() 507 { 508 #ifdef USE_ION 509 510 if (extradata_info.uaddr) { 511 munmap((void *)extradata_info.uaddr, extradata_info.size); 512 close(extradata_info.ion.fd_ion_data.fd); 513 free_ion_memory(&extradata_info.ion); 514 } 515 516 memset(&extradata_info, 0, sizeof(extradata_info)); 517 #endif 518 } 519 520 bool venc_dev::venc_open(OMX_U32 codec) 521 { 522 int r; 523 unsigned int alignment = 0,buffer_size = 0, temp =0; 524 struct v4l2_control control; 525 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc"; 526 527 char platform_name[PROPERTY_VALUE_MAX]; 528 property_get("ro.board.platform", platform_name, "0"); 529 530 if (!strncmp(platform_name, "msm8610", 7)) { 531 device_name = (OMX_STRING)"/dev/video/q6_enc"; 532 } 533 534 m_nDriver_fd = open (device_name, O_RDWR); 535 536 if (m_nDriver_fd == 0) { 537 DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n"); 538 m_nDriver_fd = open (device_name, O_RDWR); 539 } 540 541 if ((int)m_nDriver_fd < 0) { 542 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n"); 543 return false; 544 } 545 546 DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd); 547 // set the basic configuration of the video encoder driver 548 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; 549 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; 550 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; 551 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; 552 m_sVenc_cfg.fps_num = 30; 553 m_sVenc_cfg.fps_den = 1; 554 m_sVenc_cfg.targetbitrate = 64000; 555 m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12; 556 557 if (codec == OMX_VIDEO_CodingMPEG4) { 558 m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4; 559 codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; 560 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; 561 #ifdef OUTPUT_BUFFER_LOG 562 strcat(outputfilename, "m4v"); 563 #endif 564 } else if (codec == OMX_VIDEO_CodingH263) { 565 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263; 566 codec_profile.profile = VEN_PROFILE_H263_BASELINE; 567 profile_level.level = VEN_LEVEL_H263_20; 568 #ifdef OUTPUT_BUFFER_LOG 569 strcat(outputfilename, "263"); 570 #endif 571 } else if (codec == OMX_VIDEO_CodingAVC) { 572 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264; 573 codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; 574 profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; 575 #ifdef OUTPUT_BUFFER_LOG 576 strcat(outputfilename, "264"); 577 #endif 578 } else if (codec == OMX_VIDEO_CodingVPX) { 579 m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8; 580 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; 581 profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; 582 #ifdef OUTPUT_BUFFER_LOG 583 strcat(outputfilename, "ivf"); 584 #endif 585 } 586 587 #ifdef INPUT_BUFFER_LOG 588 inputBufferFile1 = fopen (inputfilename, "ab"); 589 590 if (!inputBufferFile1) 591 DEBUG_PRINT_ERROR("Input File open failed"); 592 593 #endif 594 #ifdef OUTPUT_BUFFER_LOG 595 outputBufferFile1 = fopen (outputfilename, "ab"); 596 #endif 597 int ret; 598 ret = subscribe_to_events(m_nDriver_fd); 599 600 if (ret) { 601 DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n"); 602 return false; 603 } 604 605 struct v4l2_capability cap; 606 607 struct v4l2_fmtdesc fdesc; 608 609 struct v4l2_format fmt; 610 611 struct v4l2_requestbuffers bufreq; 612 613 ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap); 614 615 if (ret) { 616 DEBUG_PRINT_ERROR("Failed to query capabilities\n"); 617 } else { 618 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," 619 " version = %d, capabilities = %x\n", cap.driver, cap.card, 620 cap.bus_info, cap.version, cap.capabilities); 621 } 622 623 ret=0; 624 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 625 fdesc.index=0; 626 627 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 628 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, 629 fdesc.pixelformat, fdesc.flags); 630 fdesc.index++; 631 } 632 633 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 634 fdesc.index=0; 635 636 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 637 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, 638 fdesc.pixelformat, fdesc.flags); 639 fdesc.index++; 640 } 641 642 m_sOutput_buff_property.alignment=m_sInput_buff_property.alignment=4096; 643 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 644 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 645 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 646 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 647 648 /*TODO: Return values not handled properly in this function anywhere. 649 * Need to handle those.*/ 650 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 651 652 if (ret) { 653 DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); 654 return false; 655 } 656 657 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 658 659 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 660 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 661 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 662 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 663 664 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 665 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 666 667 bufreq.memory = V4L2_MEMORY_USERPTR; 668 bufreq.count = 2; 669 670 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 671 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 672 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 673 674 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 675 bufreq.count = 2; 676 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 677 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 678 679 680 resume_in_stopped = 0; 681 metadatamode = 0; 682 683 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; 684 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; 685 686 DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d\n", control.id, control.value); 687 688 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) 689 DEBUG_PRINT_ERROR("Failed to set control\n"); 690 691 struct v4l2_frmsizeenum frmsize; 692 693 //Get the hardware capabilities 694 memset((void *)&frmsize,0,sizeof(frmsize)); 695 frmsize.index = 0; 696 frmsize.pixel_format = m_sVenc_cfg.codectype; 697 ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize); 698 699 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { 700 DEBUG_PRINT_ERROR("Failed to get framesizes\n"); 701 return false; 702 } 703 704 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 705 capability.min_width = frmsize.stepwise.min_width; 706 capability.max_width = frmsize.stepwise.max_width; 707 capability.min_height = frmsize.stepwise.min_height; 708 capability.max_height = frmsize.stepwise.max_height; 709 } 710 711 return true; 712 } 713 714 715 static OMX_ERRORTYPE unsubscribe_to_events(int fd) 716 { 717 OMX_ERRORTYPE eRet = OMX_ErrorNone; 718 struct v4l2_event_subscription sub; 719 int array_sz = sizeof(event_type)/sizeof(int); 720 int i,rc; 721 722 if (fd < 0) { 723 printf("Invalid input: %d\n", fd); 724 return OMX_ErrorBadParameter; 725 } 726 727 for (i = 0; i < array_sz; ++i) { 728 memset(&sub, 0, sizeof(sub)); 729 sub.type = event_type[i]; 730 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 731 732 if (rc) { 733 printf("Failed to unsubscribe event: 0x%x\n", sub.type); 734 break; 735 } 736 } 737 738 return eRet; 739 } 740 741 void venc_dev::venc_close() 742 { 743 struct v4l2_encoder_cmd enc; 744 DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd); 745 746 if ((int)m_nDriver_fd >= 0) { 747 enc.cmd = V4L2_ENC_CMD_STOP; 748 ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc); 749 DEBUG_PRINT_HIGH("venc_close E\n"); 750 751 if (async_thread_created) 752 pthread_join(m_tid,NULL); 753 754 DEBUG_PRINT_HIGH("venc_close X\n"); 755 unsubscribe_to_events(m_nDriver_fd); 756 close(m_nDriver_fd); 757 m_nDriver_fd = -1; 758 } 759 760 #ifdef INPUT_BUFFER_LOG 761 fclose (inputBufferFile1); 762 #endif 763 #ifdef OUTPUT_BUFFER_LOG 764 fclose (outputBufferFile1); 765 #endif 766 } 767 768 bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, 769 unsigned long *actual_buff_count, 770 unsigned long *buff_size, 771 unsigned long port) 772 { 773 774 unsigned long temp_count = 0; 775 776 if (port == 0) { 777 if (*actual_buff_count > m_sInput_buff_property.mincount) { 778 temp_count = m_sInput_buff_property.actualcount; 779 m_sInput_buff_property.actualcount = *actual_buff_count; 780 DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count); 781 } 782 } else { 783 if (*actual_buff_count > m_sOutput_buff_property.mincount) { 784 temp_count = m_sOutput_buff_property.actualcount; 785 m_sOutput_buff_property.actualcount = *actual_buff_count; 786 DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count); 787 } 788 } 789 790 return true; 791 792 } 793 794 bool venc_dev::venc_loaded_start() 795 { 796 return true; 797 } 798 799 bool venc_dev::venc_loaded_stop() 800 { 801 return true; 802 } 803 804 bool venc_dev::venc_loaded_start_done() 805 { 806 return true; 807 } 808 809 bool venc_dev::venc_loaded_stop_done() 810 { 811 return true; 812 } 813 814 bool venc_dev::venc_get_seq_hdr(void *buffer, 815 unsigned buffer_size, unsigned *header_len) 816 { 817 return true; 818 } 819 820 bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, 821 unsigned long *actual_buff_count, 822 unsigned long *buff_size, 823 unsigned long port) 824 { 825 struct v4l2_format fmt; 826 struct v4l2_requestbuffers bufreq; 827 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; 828 int ret; 829 830 if (port == 0) { 831 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 832 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 833 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 834 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 835 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 836 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 837 bufreq.memory = V4L2_MEMORY_USERPTR; 838 839 if (*actual_buff_count) 840 bufreq.count = *actual_buff_count; 841 else 842 bufreq.count = 2; 843 844 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 845 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 846 847 if (ret) { 848 DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n "); 849 return false; 850 } 851 852 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 853 *min_buff_count = m_sInput_buff_property.mincount; 854 *actual_buff_count = m_sInput_buff_property.actualcount; 855 #ifdef USE_ION 856 // For ION memory allocations of the allocated buffer size 857 // must be 4k aligned, hence aligning the input buffer 858 // size to 4k. 859 m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) & (~4095); 860 #endif 861 *buff_size = m_sInput_buff_property.datasize; 862 } else { 863 int extra_idx = 0; 864 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 865 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 866 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 867 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 868 869 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 870 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 871 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 872 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 873 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 874 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 875 876 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 877 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 878 bufreq.memory = V4L2_MEMORY_USERPTR; 879 880 if (*actual_buff_count) 881 bufreq.count = *actual_buff_count; 882 else 883 bufreq.count = 2; 884 885 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 886 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 887 888 if (ret) { 889 DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS CAPTURE_MPLANE Failed \n "); 890 return false; 891 } 892 893 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 894 *min_buff_count = m_sOutput_buff_property.mincount; 895 *actual_buff_count = m_sOutput_buff_property.actualcount; 896 *buff_size = m_sOutput_buff_property.datasize; 897 num_planes = fmt.fmt.pix_mp.num_planes; 898 extra_idx = EXTRADATA_IDX(num_planes); 899 900 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 901 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 902 } else if (extra_idx >= VIDEO_MAX_PLANES) { 903 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); 904 return OMX_ErrorBadParameter; 905 } 906 907 extradata_info.buffer_size = extra_data_size; 908 extradata_info.count = m_sOutput_buff_property.actualcount; 909 extradata_info.size = extradata_info.buffer_size * extradata_info.count; 910 } 911 912 return true; 913 } 914 915 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) 916 { 917 DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n"); 918 struct v4l2_format fmt; 919 struct v4l2_requestbuffers bufreq; 920 int ret; 921 922 switch (index) { 923 case OMX_IndexParamPortDefinition: 924 { 925 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 926 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 927 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n"); 928 929 if (portDefn->nPortIndex == PORT_INDEX_IN) { 930 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) { 931 return false; 932 } 933 934 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) { 935 return false; 936 } 937 938 if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight || 939 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) { 940 DEBUG_PRINT_LOW("\n Basic parameter has changed"); 941 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; 942 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; 943 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 944 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 945 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 946 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 947 948 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 949 DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT OUTPUT_MPLANE Failed \n "); 950 return false; 951 } 952 953 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 954 bufreq.memory = V4L2_MEMORY_USERPTR; 955 bufreq.count = portDefn->nBufferCountActual; 956 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 957 958 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 959 DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n "); 960 return false; 961 } 962 963 if (bufreq.count == portDefn->nBufferCountActual) 964 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 965 966 if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) 967 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; 968 } 969 970 DEBUG_PRINT_LOW("input: actual: %d, min: %d, count_req: %d\n", 971 portDefn->nBufferCountActual, m_sInput_buff_property.mincount, bufreq.count); 972 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) { 973 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 974 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 975 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 976 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 977 978 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 979 DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT CAPTURE_MPLANE Failed \n "); 980 return false; 981 } 982 983 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 984 985 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) { 986 return false; 987 } 988 989 if ((portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) 990 && (m_sOutput_buff_property.datasize == portDefn->nBufferSize)) { 991 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 992 bufreq.memory = V4L2_MEMORY_USERPTR; 993 bufreq.count = portDefn->nBufferCountActual; 994 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 995 996 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 997 DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed: requested: %lu, current: %lu", 998 portDefn->nBufferCountActual, m_sOutput_buff_property.actualcount); 999 return false; 1000 } 1001 1002 if (bufreq.count == portDefn->nBufferCountActual) 1003 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 1004 1005 if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) 1006 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 1007 1008 if (num_planes > 1) 1009 extradata_info.count = m_sOutput_buff_property.actualcount; 1010 } else { 1011 DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed"); 1012 return false; 1013 } 1014 1015 DEBUG_PRINT_LOW("Output: actual: %d, min: %d, count_req: %d\n", 1016 portDefn->nBufferCountActual, m_sOutput_buff_property.mincount, bufreq.count); 1017 } else { 1018 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); 1019 } 1020 1021 break; 1022 } 1023 case OMX_IndexParamVideoPortFormat: 1024 { 1025 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; 1026 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 1027 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n"); 1028 1029 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) { 1030 if (!venc_set_color_format(portFmt->eColorFormat)) { 1031 return false; 1032 } 1033 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1034 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) { 1035 return false; 1036 } 1037 } else { 1038 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); 1039 } 1040 1041 break; 1042 } 1043 case OMX_IndexParamVideoBitrate: 1044 { 1045 OMX_VIDEO_PARAM_BITRATETYPE* pParam; 1046 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 1047 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n"); 1048 1049 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1050 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) { 1051 DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed"); 1052 return false; 1053 } 1054 1055 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) { 1056 DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed"); 1057 return false; 1058 } 1059 } else { 1060 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); 1061 } 1062 1063 break; 1064 } 1065 case OMX_IndexParamVideoMpeg4: 1066 { 1067 OMX_VIDEO_PARAM_MPEG4TYPE* pParam; 1068 OMX_U32 bFrames = 0; 1069 1070 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 1071 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n"); 1072 1073 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1074 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) { 1075 DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed"); 1076 return false; 1077 } 1078 1079 m_profile_set = false; 1080 m_level_set = false; 1081 1082 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1083 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); 1084 return false; 1085 } else { 1086 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 1087 if (pParam->nBFrames) { 1088 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); 1089 bFrames = 1; 1090 } 1091 } else { 1092 if (pParam->nBFrames) { 1093 DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); 1094 bFrames = 0; 1095 } 1096 } 1097 } 1098 1099 if (!venc_set_intra_period (pParam->nPFrames,bFrames)) { 1100 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 1101 return false; 1102 } 1103 1104 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) { 1105 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config"); 1106 return false; 1107 } 1108 } else { 1109 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); 1110 } 1111 1112 break; 1113 } 1114 case OMX_IndexParamVideoH263: 1115 { 1116 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 1117 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n"); 1118 OMX_U32 bFrames = 0; 1119 1120 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1121 m_profile_set = false; 1122 m_level_set = false; 1123 1124 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1125 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); 1126 return false; 1127 } 1128 1129 if (pParam->nBFrames) 1130 DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263"); 1131 1132 if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) { 1133 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 1134 return false; 1135 } 1136 } else { 1137 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263"); 1138 } 1139 1140 break; 1141 } 1142 case OMX_IndexParamVideoAvc: 1143 { 1144 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n"); 1145 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 1146 OMX_U32 bFrames = 0; 1147 1148 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1149 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n", 1150 pParam->eProfile,pParam->eLevel); 1151 1152 m_profile_set = false; 1153 m_level_set = false; 1154 1155 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) { 1156 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d", 1157 pParam->eProfile, pParam->eLevel); 1158 return false; 1159 } else { 1160 if (pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) { 1161 if (pParam->nBFrames) { 1162 DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); 1163 bFrames = 1; 1164 } 1165 } else { 1166 if (pParam->nBFrames) { 1167 DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); 1168 bFrames = 0; 1169 } 1170 } 1171 } 1172 1173 if (!venc_set_intra_period (pParam->nPFrames, bFrames)) { 1174 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 1175 return false; 1176 } 1177 1178 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) { 1179 DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed"); 1180 return false; 1181 } 1182 1183 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) { 1184 DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed"); 1185 return false; 1186 } 1187 1188 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) { 1189 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config"); 1190 return false; 1191 } 1192 } else { 1193 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); 1194 } 1195 1196 //TBD, lot of other variables to be updated, yet to decide 1197 break; 1198 } 1199 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8: 1200 { 1201 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8\n"); 1202 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData; 1203 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1204 DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d", 1205 pParam->eProfile, pParam->eLevel); 1206 return false; 1207 } 1208 break; 1209 } 1210 case OMX_IndexParamVideoIntraRefresh: 1211 { 1212 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n"); 1213 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = 1214 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; 1215 1216 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1217 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) { 1218 DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); 1219 return false; 1220 } 1221 } else { 1222 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); 1223 } 1224 1225 break; 1226 } 1227 case OMX_IndexParamVideoErrorCorrection: 1228 { 1229 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n"); 1230 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = 1231 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; 1232 1233 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1234 if (venc_set_error_resilience(error_resilience) == false) { 1235 DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); 1236 return false; 1237 } 1238 } else { 1239 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); 1240 } 1241 1242 break; 1243 } 1244 case OMX_IndexParamVideoProfileLevelCurrent: 1245 { 1246 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n"); 1247 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = 1248 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 1249 1250 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1251 m_profile_set = false; 1252 m_level_set = false; 1253 1254 if (!venc_set_profile_level (profile_level->eProfile, 1255 profile_level->eLevel)) { 1256 DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); 1257 return false; 1258 } 1259 } else { 1260 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); 1261 } 1262 1263 break; 1264 } 1265 case OMX_IndexParamVideoQuantization: 1266 { 1267 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n"); 1268 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = 1269 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; 1270 1271 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1272 if (venc_set_session_qp (session_qp->nQpI, 1273 session_qp->nQpP, 1274 session_qp->nQpB) == false) { 1275 DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed"); 1276 return false; 1277 } 1278 } else { 1279 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); 1280 } 1281 1282 break; 1283 } 1284 case OMX_QcomIndexEnableSliceDeliveryMode: 1285 { 1286 QOMX_EXTNINDEX_PARAMTYPE* pParam = 1287 (QOMX_EXTNINDEX_PARAMTYPE*)paramData; 1288 1289 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1290 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) { 1291 DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); 1292 return OMX_ErrorUnsupportedSetting; 1293 } 1294 } else { 1295 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " 1296 "called on wrong port(%d)", pParam->nPortIndex); 1297 return OMX_ErrorBadPortIndex; 1298 } 1299 1300 break; 1301 } 1302 case OMX_ExtraDataVideoEncoderSliceInfo: 1303 { 1304 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); 1305 OMX_U32 extra_data = *(OMX_U32 *)paramData; 1306 1307 if (venc_set_extradata(extra_data) == false) { 1308 DEBUG_PRINT_ERROR("ERROR: Setting " 1309 "OMX_ExtraDataVideoEncoderSliceInfo failed"); 1310 return false; 1311 } 1312 1313 extradata = true; 1314 break; 1315 } 1316 case OMX_IndexParamVideoSliceFMO: 1317 default: 1318 DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u", 1319 index); 1320 break; 1321 //case 1322 } 1323 1324 return true; 1325 } 1326 1327 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) 1328 { 1329 1330 DEBUG_PRINT_LOW("\n Inside venc_set_config"); 1331 1332 switch (index) { 1333 case OMX_IndexConfigVideoBitrate: 1334 { 1335 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) 1336 configData; 1337 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate"); 1338 1339 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1340 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) { 1341 DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed"); 1342 return false; 1343 } 1344 } else { 1345 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); 1346 } 1347 1348 break; 1349 } 1350 case OMX_IndexConfigVideoFramerate: 1351 { 1352 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) 1353 configData; 1354 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate"); 1355 1356 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1357 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) { 1358 DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); 1359 return false; 1360 } 1361 } else { 1362 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 1363 } 1364 1365 break; 1366 } 1367 case QOMX_IndexConfigVideoIntraperiod: 1368 { 1369 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n"); 1370 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = 1371 (QOMX_VIDEO_INTRAPERIODTYPE *)configData; 1372 1373 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1374 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) { 1375 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 1376 return false; 1377 } 1378 } 1379 1380 break; 1381 } 1382 case OMX_IndexConfigVideoIntraVOPRefresh: 1383 { 1384 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) 1385 configData; 1386 DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); 1387 1388 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1389 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) { 1390 DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); 1391 return false; 1392 } 1393 } else { 1394 DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 1395 } 1396 1397 break; 1398 } 1399 case OMX_IndexConfigCommonRotate: 1400 { 1401 OMX_CONFIG_ROTATIONTYPE *config_rotation = 1402 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 1403 OMX_U32 nFrameWidth; 1404 1405 DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims"); 1406 nFrameWidth = m_sVenc_cfg.input_width; 1407 m_sVenc_cfg.input_width = m_sVenc_cfg.input_height; 1408 m_sVenc_cfg.input_height = nFrameWidth; 1409 1410 if (/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0) { 1411 DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed"); 1412 return false; 1413 } 1414 1415 break; 1416 } 1417 case OMX_IndexConfigVideoAVCIntraPeriod: 1418 { 1419 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; 1420 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod"); 1421 1422 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod) 1423 == false) { 1424 DEBUG_PRINT_ERROR("ERROR: Setting " 1425 "OMX_IndexConfigVideoAVCIntraPeriod failed"); 1426 return false; 1427 } 1428 1429 break; 1430 } 1431 default: 1432 DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index); 1433 break; 1434 } 1435 1436 return true; 1437 } 1438 1439 unsigned venc_dev::venc_stop( void) 1440 { 1441 struct venc_msg venc_msg; 1442 struct v4l2_requestbuffers bufreq; 1443 int rc = 0, ret = 0; 1444 1445 if (!stopped) { 1446 enum v4l2_buf_type cap_type; 1447 1448 if (streaming[OUTPUT_PORT]) { 1449 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1450 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); 1451 1452 if (rc) { 1453 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n", 1454 cap_type, rc); 1455 } else 1456 streaming[OUTPUT_PORT] = false; 1457 1458 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port"); 1459 bufreq.memory = V4L2_MEMORY_USERPTR; 1460 bufreq.count = 0; 1461 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1462 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); 1463 1464 if (ret) { 1465 DEBUG_PRINT_ERROR("\nERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed \n "); 1466 return false; 1467 } 1468 } 1469 1470 if (!rc && streaming[CAPTURE_PORT]) { 1471 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1472 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); 1473 1474 if (rc) { 1475 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n", 1476 cap_type, rc); 1477 } else 1478 streaming[CAPTURE_PORT] = false; 1479 1480 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port"); 1481 bufreq.memory = V4L2_MEMORY_USERPTR; 1482 bufreq.count = 0; 1483 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1484 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); 1485 1486 if (ret) { 1487 DEBUG_PRINT_ERROR("\nERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed \n "); 1488 return false; 1489 } 1490 } 1491 1492 if (!rc && !ret) { 1493 venc_stop_done(); 1494 stopped = 1; 1495 /*set flag to re-configure when started again*/ 1496 resume_in_stopped = 1; 1497 1498 } 1499 } 1500 1501 return rc; 1502 } 1503 1504 unsigned venc_dev::venc_pause(void) 1505 { 1506 pthread_mutex_lock(&pause_resume_mlock); 1507 paused = true; 1508 pthread_mutex_unlock(&pause_resume_mlock); 1509 return 0; 1510 } 1511 1512 unsigned venc_dev::venc_resume(void) 1513 { 1514 pthread_mutex_lock(&pause_resume_mlock); 1515 paused = false; 1516 pthread_mutex_unlock(&pause_resume_mlock); 1517 1518 return pthread_cond_signal(&pause_resume_cond); 1519 } 1520 1521 unsigned venc_dev::venc_start_done(void) 1522 { 1523 struct venc_msg venc_msg; 1524 venc_msg.msgcode = VEN_MSG_START; 1525 venc_msg.statuscode = VEN_S_SUCCESS; 1526 venc_handle->async_message_process(venc_handle,&venc_msg); 1527 return 0; 1528 } 1529 1530 unsigned venc_dev::venc_stop_done(void) 1531 { 1532 struct venc_msg venc_msg; 1533 free_extradata(); 1534 venc_msg.msgcode=VEN_MSG_STOP; 1535 venc_msg.statuscode=VEN_S_SUCCESS; 1536 venc_handle->async_message_process(venc_handle,&venc_msg); 1537 return 0; 1538 } 1539 1540 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid) 1541 { 1542 async_thread_created = true; 1543 m_tid=tid; 1544 return 0; 1545 } 1546 1547 1548 unsigned venc_dev::venc_start(void) 1549 { 1550 enum v4l2_buf_type buf_type; 1551 int ret,r; 1552 struct v4l2_control control = {0}; 1553 1554 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start", 1555 __func__); 1556 1557 if (!venc_set_profile_level(0, 0)) { 1558 DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET", 1559 __func__); 1560 } else { 1561 DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET", 1562 __func__, codec_profile.profile, profile_level.level); 1563 } 1564 1565 venc_config_print(); 1566 1567 if(resume_in_stopped){ 1568 /*set buffercount when restarted*/ 1569 venc_reconfig_reqbufs(); 1570 resume_in_stopped = 0; 1571 } 1572 1573 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */ 1574 if (slice_mode.enable && multislice.mslice_size && 1575 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) { 1576 DEBUG_PRINT_ERROR("slice_mode: %d, max slices (%d) should be less than (%d)\n", slice_mode.enable, 1577 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size), 1578 MAX_SUPPORTED_SLICES_PER_FRAME); 1579 return 1; 1580 } 1581 1582 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1583 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); 1584 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type); 1585 1586 if (ret) 1587 return 1; 1588 1589 streaming[CAPTURE_PORT] = true; 1590 1591 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER; 1592 control.value = 1; 1593 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 1594 if (ret) { 1595 DEBUG_PRINT_ERROR("failed to request seq header"); 1596 return 1; 1597 } 1598 1599 stopped = 0; 1600 return 0; 1601 } 1602 1603 void venc_dev::venc_config_print() 1604 { 1605 1606 DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %ld, Profile %ld, level : %ld", 1607 m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); 1608 1609 DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %ld, Height:%ld, Fps: %ld", 1610 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, 1611 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); 1612 1613 DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld", 1614 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); 1615 1616 DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld", 1617 session_qp.iframeqp, session_qp.pframqp,session_qp.bframqp); 1618 1619 DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld", 1620 voptimecfg.voptime_resolution, multislice.mslice_mode, 1621 multislice.mslice_size); 1622 1623 DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %ld", 1624 entropy.longentropysel, entropy.cabacmodel); 1625 1626 DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld\n", 1627 dbkfilter.db_mode, dbkfilter.slicealpha_offset, 1628 dbkfilter.slicebeta_offset); 1629 1630 DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld\n", 1631 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod); 1632 1633 } 1634 1635 bool venc_dev::venc_reconfig_reqbufs() 1636 { 1637 struct v4l2_requestbuffers bufreq; 1638 1639 bufreq.memory = V4L2_MEMORY_USERPTR; 1640 bufreq.count = m_sInput_buff_property.actualcount; 1641 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1642 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 1643 DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume\n"); 1644 return false; 1645 } 1646 1647 bufreq.memory = V4L2_MEMORY_USERPTR; 1648 bufreq.count = m_sOutput_buff_property.actualcount; 1649 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1650 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) 1651 { 1652 DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed when resume\n"); 1653 return false; 1654 } 1655 return true; 1656 } 1657 1658 unsigned venc_dev::venc_flush( unsigned port) 1659 { 1660 struct v4l2_encoder_cmd enc; 1661 DEBUG_PRINT_LOW("in %s", __func__); 1662 1663 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH; 1664 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE; 1665 1666 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) { 1667 DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", port); 1668 return -1; 1669 } 1670 1671 return 0; 1672 1673 } 1674 1675 //allocating I/P memory from pmem and register with the device 1676 1677 1678 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index) 1679 { 1680 1681 struct pmem *pmem_tmp; 1682 struct v4l2_buffer buf; 1683 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 1684 int rc = 0, extra_idx; 1685 1686 pmem_tmp = (struct pmem *)buf_addr; 1687 DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); 1688 1689 if (port == PORT_INDEX_IN) { 1690 buf.index = index; 1691 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1692 buf.memory = V4L2_MEMORY_USERPTR; 1693 plane[0].length = pmem_tmp->size; 1694 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; 1695 plane[0].reserved[0] = pmem_tmp->fd; 1696 plane[0].reserved[1] = 0; 1697 plane[0].data_offset = pmem_tmp->offset; 1698 buf.m.planes = plane; 1699 buf.length = 1; 1700 1701 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); 1702 1703 if (rc) 1704 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n"); 1705 } else if (port == PORT_INDEX_OUT) { 1706 extra_idx = EXTRADATA_IDX(num_planes); 1707 1708 if ((num_planes > 1) && (extra_idx)) { 1709 rc = allocate_extradata(); 1710 1711 if (rc) 1712 DEBUG_PRINT_ERROR("Failed to allocate extradata: %d\n", rc); 1713 } 1714 1715 buf.index = index; 1716 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1717 buf.memory = V4L2_MEMORY_USERPTR; 1718 plane[0].length = pmem_tmp->size; 1719 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; 1720 plane[0].reserved[0] = pmem_tmp->fd; 1721 plane[0].reserved[1] = 0; 1722 plane[0].data_offset = pmem_tmp->offset; 1723 buf.m.planes = plane; 1724 buf.length = num_planes; 1725 1726 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 1727 plane[extra_idx].length = extradata_info.buffer_size; 1728 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); 1729 #ifdef USE_ION 1730 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; 1731 #endif 1732 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; 1733 plane[extra_idx].data_offset = 0; 1734 } else if (extra_idx >= VIDEO_MAX_PLANES) { 1735 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); 1736 return OMX_ErrorBadParameter; 1737 } 1738 1739 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); 1740 1741 if (rc) 1742 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n"); 1743 } else { 1744 DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index "); 1745 return false; 1746 } 1747 1748 return true; 1749 } 1750 1751 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) 1752 { 1753 struct pmem *pmem_tmp; 1754 struct venc_bufferpayload dev_buffer; 1755 1756 memset(&dev_buffer, 0, sizeof(dev_buffer)); 1757 pmem_tmp = (struct pmem *)buf_addr; 1758 1759 if (port == PORT_INDEX_IN) { 1760 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 1761 dev_buffer.fd = pmem_tmp->fd; 1762 dev_buffer.maped_size = pmem_tmp->size; 1763 dev_buffer.sz = pmem_tmp->size; 1764 dev_buffer.offset = pmem_tmp->offset; 1765 DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 1766 dev_buffer.pbuffer, \ 1767 dev_buffer.fd, \ 1768 dev_buffer.offset, \ 1769 dev_buffer.maped_size); 1770 1771 } else if (port == PORT_INDEX_OUT) { 1772 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 1773 dev_buffer.fd = pmem_tmp->fd; 1774 dev_buffer.sz = pmem_tmp->size; 1775 dev_buffer.maped_size = pmem_tmp->size; 1776 dev_buffer.offset = pmem_tmp->offset; 1777 1778 DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ 1779 dev_buffer.pbuffer, \ 1780 dev_buffer.fd, \ 1781 dev_buffer.offset, \ 1782 dev_buffer.maped_size); 1783 } else { 1784 DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index "); 1785 return false; 1786 } 1787 1788 return true; 1789 } 1790 1791 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer, 1792 OMX_U32 width, OMX_U32 height) 1793 { 1794 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width), 1795 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height), 1796 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width), 1797 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height), 1798 src_chroma_offset = width * height; 1799 1800 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) { 1801 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer; 1802 //Do chroma first, so that we can convert it in-place 1803 src_buf += width * height; 1804 dst_buf += y_stride * y_scanlines; 1805 for (int line = height / 2 - 1; line >= 0; --line) { 1806 memmove(dst_buf + line * uv_stride, 1807 src_buf + line * width, 1808 width); 1809 } 1810 1811 dst_buf = src_buf = buffer->pBuffer; 1812 //Copy the Y next 1813 for (int line = height - 1; line > 0; --line) { 1814 memmove(dst_buf + line * y_stride, 1815 src_buf + line * width, 1816 width); 1817 } 1818 } else { 1819 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \ 1820 Insufficient bufferLen=%u v/s Required=%u", 1821 (width*height), src_chroma_offset, buffer->nAllocLen, 1822 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)); 1823 return false; 1824 } 1825 1826 return true; 1827 } 1828 1829 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd) 1830 { 1831 struct pmem *temp_buffer; 1832 struct v4l2_buffer buf; 1833 struct v4l2_plane plane; 1834 int rc=0; 1835 struct OMX_BUFFERHEADERTYPE *bufhdr; 1836 encoder_media_buffer_type * meta_buf = NULL; 1837 temp_buffer = (struct pmem *)buffer; 1838 1839 memset (&buf, 0, sizeof(buf)); 1840 memset (&plane, 0, sizeof(plane)); 1841 1842 if (buffer == NULL) { 1843 DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL"); 1844 return false; 1845 } 1846 1847 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 1848 1849 DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen); 1850 1851 if (pmem_data_buf) { 1852 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 1853 plane.m.userptr = (unsigned long)pmem_data_buf; 1854 plane.data_offset = bufhdr->nOffset; 1855 plane.length = bufhdr->nAllocLen; 1856 plane.bytesused = bufhdr->nFilledLen; 1857 } else { 1858 // -------------------------------------------------------------------------------------- 1859 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info] 1860 // --------------------------------------------------------------------------------------- 1861 // Camera-2 1 CameraSource 0 meta-handle 1862 // Camera-3 1 GrallocSource 0 gralloc-private-handle 1863 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted) 1864 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr 1865 // --------------------------------------------------------------------------------------- 1866 if (metadatamode) { 1867 plane.m.userptr = index; 1868 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer; 1869 1870 if (!meta_buf) { 1871 //empty EOS buffer 1872 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) { 1873 plane.data_offset = bufhdr->nOffset; 1874 plane.length = bufhdr->nAllocLen; 1875 plane.bytesused = bufhdr->nFilledLen; 1876 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer"); 1877 } else { 1878 return false; 1879 } 1880 } else if (!color_format) { 1881 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) { 1882 plane.data_offset = meta_buf->meta_handle->data[1]; 1883 plane.length = meta_buf->meta_handle->data[2]; 1884 plane.bytesused = meta_buf->meta_handle->data[2]; 1885 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d", 1886 fd, plane.bytesused, plane.length); 1887 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) { 1888 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle; 1889 fd = handle->fd; 1890 plane.data_offset = 0; 1891 plane.length = handle->size; 1892 plane.bytesused = handle->size; 1893 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d " 1894 ": filled %d of %d", fd, plane.bytesused, plane.length); 1895 } 1896 } else { 1897 plane.data_offset = bufhdr->nOffset; 1898 plane.length = bufhdr->nAllocLen; 1899 plane.bytesused = bufhdr->nFilledLen; 1900 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d " 1901 ": filled %d of %d", fd, plane.bytesused, plane.length); 1902 } 1903 } else { 1904 plane.data_offset = bufhdr->nOffset; 1905 plane.length = bufhdr->nAllocLen; 1906 plane.bytesused = bufhdr->nFilledLen; 1907 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d", 1908 fd, plane.bytesused, plane.length); 1909 } 1910 } 1911 1912 buf.index = index; 1913 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1914 buf.memory = V4L2_MEMORY_USERPTR; 1915 plane.reserved[0] = fd; 1916 plane.reserved[1] = 0; 1917 buf.m.planes = &plane; 1918 buf.length = 1; 1919 1920 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) 1921 buf.flags = V4L2_BUF_FLAG_EOS; 1922 1923 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000; 1924 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000); 1925 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 1926 1927 if (rc) { 1928 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver"); 1929 return false; 1930 } 1931 1932 etb++; 1933 1934 if (!streaming[OUTPUT_PORT]) { 1935 enum v4l2_buf_type buf_type; 1936 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1937 int ret; 1938 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type); 1939 1940 if (ret) { 1941 DEBUG_PRINT_ERROR("Failed to call streamon\n"); 1942 return false; 1943 } else { 1944 streaming[OUTPUT_PORT] = true; 1945 } 1946 } 1947 1948 #ifdef INPUT_BUFFER_LOG 1949 int i; 1950 int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width); 1951 int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height); 1952 char *temp = (char *)bufhdr->pBuffer; 1953 1954 for (i = 0; i < m_sVenc_cfg.input_height; i++) { 1955 fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1); 1956 temp += stride; 1957 } 1958 1959 temp = (char *)bufhdr->pBuffer + (stride * scanlines); 1960 1961 for (i = 0; i < m_sVenc_cfg.input_height/2; i++) { 1962 fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1); 1963 temp += stride; 1964 } 1965 1966 #endif 1967 return true; 1968 } 1969 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) 1970 { 1971 struct pmem *temp_buffer = NULL; 1972 struct venc_buffer frameinfo; 1973 struct v4l2_buffer buf; 1974 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 1975 int rc = 0, extra_idx; 1976 struct OMX_BUFFERHEADERTYPE *bufhdr; 1977 1978 if (buffer == NULL) 1979 return false; 1980 1981 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 1982 1983 if (pmem_data_buf) { 1984 DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); 1985 plane[0].m.userptr = (unsigned long)pmem_data_buf; 1986 } else { 1987 DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 1988 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer; 1989 } 1990 1991 buf.index = index; 1992 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1993 buf.memory = V4L2_MEMORY_USERPTR; 1994 plane[0].length = bufhdr->nAllocLen; 1995 plane[0].bytesused = bufhdr->nFilledLen; 1996 plane[0].reserved[0] = fd; 1997 plane[0].reserved[1] = 0; 1998 plane[0].data_offset = bufhdr->nOffset; 1999 buf.m.planes = plane; 2000 buf.length = num_planes; 2001 2002 extra_idx = EXTRADATA_IDX(num_planes); 2003 2004 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 2005 plane[extra_idx].bytesused = 0; 2006 plane[extra_idx].length = extradata_info.buffer_size; 2007 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); 2008 #ifdef USE_ION 2009 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; 2010 #endif 2011 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; 2012 plane[extra_idx].data_offset = 0; 2013 } else if (extra_idx >= VIDEO_MAX_PLANES) { 2014 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); 2015 return false; 2016 } 2017 2018 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 2019 2020 if (rc) { 2021 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver"); 2022 return false; 2023 } 2024 2025 ftb++; 2026 return true; 2027 } 2028 2029 bool venc_dev::venc_set_extradata(OMX_U32 extra_data) 2030 { 2031 struct v4l2_control control; 2032 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 2033 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO; 2034 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data); 2035 2036 if (multislice.mslice_mode && multislice.mslice_mode != V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) { 2037 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 2038 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); 2039 return false; 2040 } 2041 } else { 2042 DEBUG_PRINT_ERROR("Failed to set slice extradata, slice_mode " 2043 "is set to [%lu]", multislice.mslice_mode); 2044 } 2045 2046 return true; 2047 } 2048 2049 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable) 2050 { 2051 struct v4l2_control control; 2052 2053 if (enable) { 2054 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE; 2055 control.value = 1; 2056 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value); 2057 2058 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2059 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 2060 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); 2061 return false; 2062 } else { 2063 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d\n", control.id, control.value); 2064 slice_mode.enable = 1; 2065 } 2066 } else { 2067 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%d] " 2068 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode, 2069 m_sVenc_cfg.codectype); 2070 } 2071 } else { 2072 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled\n"); 2073 } 2074 2075 return true; 2076 } 2077 2078 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp) 2079 { 2080 int rc; 2081 struct v4l2_control control; 2082 2083 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; 2084 control.value = i_frame_qp; 2085 2086 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2087 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2088 2089 if (rc) { 2090 DEBUG_PRINT_ERROR("Failed to set control\n"); 2091 return false; 2092 } 2093 2094 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2095 session_qp.iframeqp = control.value; 2096 2097 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; 2098 control.value = p_frame_qp; 2099 2100 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2101 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2102 2103 if (rc) { 2104 DEBUG_PRINT_ERROR("Failed to set control\n"); 2105 return false; 2106 } 2107 2108 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2109 2110 session_qp.pframqp = control.value; 2111 2112 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) || 2113 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { 2114 2115 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; 2116 control.value = b_frame_qp; 2117 2118 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2119 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2120 2121 if (rc) { 2122 DEBUG_PRINT_ERROR("Failed to set control\n"); 2123 return false; 2124 } 2125 2126 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2127 2128 session_qp.bframqp = control.value; 2129 } 2130 2131 return true; 2132 } 2133 2134 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) 2135 { 2136 struct venc_profile requested_profile = {0}; 2137 struct ven_profilelevel requested_level = {0}; 2138 unsigned long mb_per_frame = 0; 2139 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d", 2140 eProfile, eLevel); 2141 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* 2142 ((m_sVenc_cfg.input_width + 15) >> 4); 2143 2144 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) { 2145 DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start"); 2146 return true; 2147 } 2148 2149 DEBUG_PRINT_LOW("\n Validating Profile/Level from table"); 2150 2151 if (!venc_validate_profile_level(&eProfile, &eLevel)) { 2152 DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed"); 2153 return false; 2154 } 2155 2156 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 2157 DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " 2158 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, 2159 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); 2160 2161 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 2162 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; 2163 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 2164 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE; 2165 } else { 2166 DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u", 2167 eProfile); 2168 return false; 2169 } 2170 2171 DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," 2172 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," 2173 "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, 2174 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); 2175 2176 if (mb_per_frame >= 3600) { 2177 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) 2178 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 2179 2180 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) 2181 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 2182 } else { 2183 switch (eLevel) { 2184 case OMX_VIDEO_MPEG4Level0: 2185 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0; 2186 break; 2187 case OMX_VIDEO_MPEG4Level0b: 2188 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B; 2189 break; 2190 case OMX_VIDEO_MPEG4Level1: 2191 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1; 2192 break; 2193 case OMX_VIDEO_MPEG4Level2: 2194 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; 2195 break; 2196 case OMX_VIDEO_MPEG4Level3: 2197 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3; 2198 break; 2199 case OMX_VIDEO_MPEG4Level4a: 2200 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4; 2201 break; 2202 case OMX_VIDEO_MPEG4Level5: 2203 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 2204 break; 2205 default: 2206 return false; 2207 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 2208 break; 2209 } 2210 } 2211 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 2212 2213 switch (eProfile) { 2214 case OMX_VIDEO_H263ProfileBaseline: 2215 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE; 2216 break; 2217 case OMX_VIDEO_H263ProfileH320Coding: 2218 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING; 2219 break; 2220 case OMX_VIDEO_H263ProfileBackwardCompatible: 2221 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE; 2222 break; 2223 case OMX_VIDEO_H263ProfileISWV2: 2224 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2; 2225 break; 2226 case OMX_VIDEO_H263ProfileISWV3: 2227 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3; 2228 break; 2229 case OMX_VIDEO_H263ProfileHighCompression: 2230 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION; 2231 break; 2232 case OMX_VIDEO_H263ProfileInternet: 2233 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET; 2234 break; 2235 case OMX_VIDEO_H263ProfileInterlace: 2236 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE; 2237 break; 2238 case OMX_VIDEO_H263ProfileHighLatency: 2239 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY; 2240 break; 2241 default: 2242 DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u", 2243 requested_profile.profile); 2244 return false; 2245 } 2246 2247 //profile level 2248 switch (eLevel) { 2249 case OMX_VIDEO_H263Level10: 2250 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0; 2251 break; 2252 case OMX_VIDEO_H263Level20: 2253 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0; 2254 break; 2255 case OMX_VIDEO_H263Level30: 2256 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0; 2257 break; 2258 case OMX_VIDEO_H263Level40: 2259 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0; 2260 break; 2261 case OMX_VIDEO_H263Level45: 2262 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5; 2263 break; 2264 case OMX_VIDEO_H263Level50: 2265 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0; 2266 break; 2267 case OMX_VIDEO_H263Level60: 2268 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0; 2269 break; 2270 case OMX_VIDEO_H263Level70: 2271 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0; 2272 break; 2273 default: 2274 return false; 2275 break; 2276 } 2277 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2278 if (eProfile == OMX_VIDEO_AVCProfileBaseline) { 2279 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; 2280 } else if (eProfile == OMX_VIDEO_AVCProfileMain) { 2281 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN; 2282 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) { 2283 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED; 2284 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) { 2285 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; 2286 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) { 2287 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10; 2288 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) { 2289 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422; 2290 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) { 2291 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE; 2292 } else { 2293 DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u", 2294 requested_profile.profile); 2295 return false; 2296 } 2297 2298 //profile level 2299 switch (eLevel) { 2300 case OMX_VIDEO_AVCLevel1: 2301 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; 2302 break; 2303 case OMX_VIDEO_AVCLevel1b: 2304 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B; 2305 break; 2306 case OMX_VIDEO_AVCLevel11: 2307 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1; 2308 break; 2309 case OMX_VIDEO_AVCLevel12: 2310 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2; 2311 break; 2312 case OMX_VIDEO_AVCLevel13: 2313 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3; 2314 break; 2315 case OMX_VIDEO_AVCLevel2: 2316 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0; 2317 break; 2318 case OMX_VIDEO_AVCLevel21: 2319 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1; 2320 break; 2321 case OMX_VIDEO_AVCLevel22: 2322 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2; 2323 break; 2324 case OMX_VIDEO_AVCLevel3: 2325 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0; 2326 break; 2327 case OMX_VIDEO_AVCLevel31: 2328 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1; 2329 break; 2330 case OMX_VIDEO_AVCLevel32: 2331 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2; 2332 break; 2333 case OMX_VIDEO_AVCLevel4: 2334 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; 2335 break; 2336 case OMX_VIDEO_AVCLevel41: 2337 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; 2338 break; 2339 case OMX_VIDEO_AVCLevel42: 2340 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2; 2341 break; 2342 case OMX_VIDEO_AVCLevel5: 2343 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0; 2344 break; 2345 case OMX_VIDEO_AVCLevel51: 2346 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1; 2347 break; 2348 default : 2349 DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %lu", 2350 requested_level.level); 2351 return false; 2352 break; 2353 } 2354 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 2355 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) { 2356 DEBUG_PRINT_ERROR("\nERROR: Unsupported VP8 profile = %u", 2357 eProfile); 2358 return false; 2359 } 2360 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; 2361 m_profile_set = true; 2362 switch(eLevel) { 2363 case OMX_VIDEO_VP8Level_Version0: 2364 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; 2365 break; 2366 case OMX_VIDEO_VP8Level_Version1: 2367 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1; 2368 break; 2369 default: 2370 DEBUG_PRINT_ERROR("\nERROR: Unsupported VP8 level= %lu", 2371 eLevel); 2372 return false; 2373 break; 2374 } 2375 } 2376 2377 if (!m_profile_set) { 2378 int rc; 2379 struct v4l2_control control; 2380 2381 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2382 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; 2383 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 2384 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE; 2385 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 2386 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE; 2387 } else { 2388 DEBUG_PRINT_ERROR("\n Wrong CODEC \n"); 2389 return false; 2390 } 2391 2392 control.value = requested_profile.profile; 2393 2394 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2395 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2396 2397 if (rc) { 2398 DEBUG_PRINT_ERROR("Failed to set control\n"); 2399 return false; 2400 } 2401 2402 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2403 2404 codec_profile.profile = control.value; 2405 m_profile_set = true; 2406 } 2407 2408 if (!m_level_set) { 2409 int rc; 2410 struct v4l2_control control; 2411 2412 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2413 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; 2414 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 2415 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL; 2416 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 2417 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL; 2418 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 2419 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL; 2420 } else { 2421 DEBUG_PRINT_ERROR("\n Wrong CODEC \n"); 2422 return false; 2423 } 2424 2425 control.value = requested_level.level; 2426 2427 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2428 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2429 2430 if (rc) { 2431 DEBUG_PRINT_ERROR("Failed to set control\n"); 2432 return false; 2433 } 2434 2435 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2436 2437 profile_level.level = control.value; 2438 m_level_set = true; 2439 } 2440 2441 return true; 2442 } 2443 2444 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) 2445 { 2446 2447 struct venc_voptimingcfg vop_timing_cfg; 2448 2449 DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u", 2450 TimeIncRes); 2451 2452 vop_timing_cfg.voptime_resolution = TimeIncRes; 2453 2454 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; 2455 return true; 2456 } 2457 2458 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) 2459 { 2460 2461 DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u", 2462 nPFrames); 2463 int rc; 2464 struct v4l2_control control; 2465 2466 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) && 2467 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && 2468 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { 2469 nBFrames=0; 2470 } 2471 2472 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 2473 control.value = nPFrames; 2474 2475 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2476 2477 if (rc) { 2478 DEBUG_PRINT_ERROR("Failed to set control\n"); 2479 return false; 2480 } 2481 2482 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2483 2484 intra_period.num_pframes = control.value; 2485 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; 2486 control.value = nBFrames; 2487 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2488 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2489 2490 if (rc) { 2491 DEBUG_PRINT_ERROR("Failed to set control\n"); 2492 return false; 2493 } 2494 2495 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2496 2497 2498 intra_period.num_bframes = control.value; 2499 2500 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2501 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 2502 control.value = 1; 2503 2504 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2505 2506 if (rc) { 2507 DEBUG_PRINT_ERROR("Failed to set control\n"); 2508 return false; 2509 } 2510 2511 idrperiod.idrperiod = 1; 2512 } 2513 2514 return true; 2515 } 2516 2517 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod) 2518 { 2519 int rc = 0; 2520 struct v4l2_control control; 2521 DEBUG_PRINT_LOW("\n venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u\n", 2522 nPFrames, nIDRPeriod); 2523 2524 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) { 2525 DEBUG_PRINT_ERROR("\nERROR: IDR period valid for H264 only!!"); 2526 return false; 2527 } 2528 2529 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) { 2530 DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); 2531 return false; 2532 } 2533 2534 intra_period.num_pframes = nPFrames; 2535 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 2536 control.value = nIDRPeriod; 2537 2538 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2539 2540 if (rc) { 2541 DEBUG_PRINT_ERROR("Failed to set control\n"); 2542 return false; 2543 } 2544 2545 idrperiod.idrperiod = nIDRPeriod; 2546 return true; 2547 } 2548 2549 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) 2550 { 2551 int rc = 0; 2552 struct v4l2_control control; 2553 2554 DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level); 2555 2556 if (enable &&(codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE)) { 2557 2558 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC; 2559 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 2560 2561 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2562 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2563 2564 if (rc) { 2565 DEBUG_PRINT_ERROR("Failed to set control\n"); 2566 return false; 2567 } 2568 2569 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2570 entropy.longentropysel = control.value; 2571 2572 if (i_cabac_level == 0) { 2573 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0; 2574 } else if (i_cabac_level == 1) { 2575 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1; 2576 } else if (i_cabac_level == 2) { 2577 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2; 2578 } 2579 2580 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL; 2581 //control.value = entropy_cfg.cabacmodel; 2582 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2583 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2584 2585 if (rc) { 2586 DEBUG_PRINT_ERROR("Failed to set control\n"); 2587 return false; 2588 } 2589 2590 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2591 entropy.cabacmodel=control.value; 2592 } else if (!enable) { 2593 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; 2594 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 2595 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2596 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2597 2598 if (rc) { 2599 DEBUG_PRINT_ERROR("Failed to set control\n"); 2600 return false; 2601 } 2602 2603 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2604 entropy.longentropysel=control.value; 2605 } else { 2606 DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile"); 2607 return false; 2608 } 2609 2610 return true; 2611 } 2612 2613 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB 2614 { 2615 int rc; 2616 struct v4l2_control control; 2617 bool status = true; 2618 2619 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) { 2620 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB; 2621 } else { 2622 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; 2623 } 2624 2625 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 2626 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2627 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2628 2629 if (rc) { 2630 DEBUG_PRINT_ERROR("Failed to set control\n"); 2631 return false; 2632 } 2633 2634 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2635 multislice.mslice_mode=control.value; 2636 2637 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) { 2638 2639 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; 2640 control.value = nSlicesize; 2641 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2642 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2643 2644 if (rc) { 2645 DEBUG_PRINT_ERROR("Failed to set control\n"); 2646 return false; 2647 } 2648 2649 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2650 multislice.mslice_size=control.value; 2651 2652 } 2653 2654 return status; 2655 } 2656 2657 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) 2658 { 2659 bool status = true; 2660 int rc; 2661 struct v4l2_control control_mode,control_mbs; 2662 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE; 2663 2664 // There is no disabled mode. Disabled mode is indicated by a 0 count. 2665 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) { 2666 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE; 2667 return status; 2668 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && 2669 (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) { 2670 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC; 2671 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS; 2672 control_mbs.value=irMBs; 2673 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) && 2674 (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) { 2675 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE; 2676 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS; 2677 control_mbs.value=irMBs; 2678 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) && 2679 (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) { 2680 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE; 2681 } else { 2682 DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:" 2683 "mb count: %lu, mb mode:%d", irMBs, ir_mode); 2684 return false; 2685 } 2686 2687 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%lu, val=%lu\n", control_mode.id, control_mode.value); 2688 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode); 2689 2690 if (rc) { 2691 DEBUG_PRINT_ERROR("Failed to set control\n"); 2692 return false; 2693 } 2694 2695 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mode.id, control_mode.value); 2696 2697 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control_mbs.id, control_mbs.value); 2698 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs); 2699 2700 if (rc) { 2701 DEBUG_PRINT_ERROR("Failed to set control\n"); 2702 return false; 2703 } 2704 2705 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mbs.id, control_mbs.value); 2706 2707 intra_refresh.irmode = control_mode.value; 2708 intra_refresh.mbcount = control_mbs.value; 2709 2710 return status; 2711 } 2712 2713 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) 2714 { 2715 bool status = true; 2716 struct venc_headerextension hec_cfg; 2717 struct venc_multiclicecfg multislice_cfg; 2718 int rc; 2719 struct v4l2_control control; 2720 2721 memset(&control, 0, sizeof(control)); 2722 2723 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 2724 if (error_resilience->bEnableHEC) { 2725 hec_cfg.header_extension = 1; 2726 } else { 2727 hec_cfg.header_extension = 0; 2728 } 2729 2730 hec.header_extension = error_resilience->bEnableHEC; 2731 } 2732 2733 if (error_resilience->bEnableRVLC) { 2734 DEBUG_PRINT_ERROR("\n RVLC is not Supported"); 2735 return false; 2736 } 2737 2738 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && 2739 (error_resilience->bEnableDataPartitioning)) { 2740 DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264"); 2741 return false; 2742 } 2743 2744 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && 2745 (error_resilience->nResynchMarkerSpacing)) { 2746 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; 2747 multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; 2748 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 2749 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES; 2750 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 && 2751 error_resilience->bEnableDataPartitioning) { 2752 multislice_cfg.mslice_mode = VEN_MSLICE_GOB; 2753 multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; 2754 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 2755 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB; 2756 } else { 2757 multislice_cfg.mslice_mode = VEN_MSLICE_OFF; 2758 multislice_cfg.mslice_size = 0; 2759 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 2760 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; 2761 } 2762 2763 DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, 2764 multislice_cfg.mslice_mode, multislice_cfg.mslice_size); 2765 printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); 2766 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2767 2768 if (rc) { 2769 printf("Failed to set Slice mode control\n"); 2770 return false; 2771 } 2772 2773 printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); 2774 multislice.mslice_mode=control.value; 2775 2776 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; 2777 control.value = error_resilience->nResynchMarkerSpacing; 2778 printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); 2779 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2780 2781 if (rc) { 2782 printf("Failed to set MAX MB control\n"); 2783 return false; 2784 } 2785 2786 printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); 2787 multislice.mslice_mode = multislice_cfg.mslice_mode; 2788 multislice.mslice_size = multislice_cfg.mslice_size; 2789 return status; 2790 } 2791 2792 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) 2793 { 2794 int rc; 2795 struct v4l2_control control; 2796 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE; 2797 2798 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) { 2799 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED; 2800 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) { 2801 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED; 2802 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) { 2803 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY; 2804 } 2805 2806 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2807 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2808 2809 if (rc) { 2810 return false; 2811 } 2812 2813 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2814 2815 dbkfilter.db_mode=control.value; 2816 2817 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA; 2818 control.value=0; 2819 2820 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2821 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2822 2823 if (rc) { 2824 return false; 2825 } 2826 2827 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2828 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA; 2829 control.value=0; 2830 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2831 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2832 2833 if (rc) { 2834 return false; 2835 } 2836 2837 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2838 2839 2840 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; 2841 return true; 2842 } 2843 2844 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) 2845 { 2846 DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u", 2847 nTargetBitrate); 2848 struct v4l2_control control; 2849 int rc = 0; 2850 control.id = V4L2_CID_MPEG_VIDEO_BITRATE; 2851 control.value = nTargetBitrate; 2852 2853 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2854 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2855 2856 if (rc) { 2857 DEBUG_PRINT_ERROR("Failed to set control\n"); 2858 return false; 2859 } 2860 2861 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 2862 2863 2864 m_sVenc_cfg.targetbitrate = control.value; 2865 bitrate.target_bitrate = control.value; 2866 2867 if (!config) { 2868 m_level_set = false; 2869 2870 if (venc_set_profile_level(0, 0)) { 2871 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu\n",profile_level.level); 2872 } 2873 } 2874 2875 return true; 2876 } 2877 2878 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) 2879 { 2880 struct v4l2_streamparm parm; 2881 int rc = 0; 2882 struct venc_framerate frame_rate_cfg; 2883 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); 2884 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2885 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator; 2886 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator; 2887 2888 if (frame_rate_cfg.fps_numerator > 0) 2889 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm); 2890 2891 if (rc) { 2892 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed\n"); 2893 return false; 2894 } 2895 2896 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; 2897 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; 2898 2899 if (!config) { 2900 m_level_set = false; 2901 2902 if (venc_set_profile_level(0, 0)) { 2903 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu\n",profile_level.level); 2904 } 2905 } 2906 2907 return true; 2908 } 2909 2910 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) 2911 { 2912 struct v4l2_format fmt; 2913 DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format); 2914 2915 if (color_format == OMX_COLOR_FormatYUV420SemiPlanar || 2916 color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { 2917 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 2918 } else if (color_format == QOMX_COLOR_FormatYVU420SemiPlanar) { 2919 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21; 2920 } else { 2921 DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format); 2922 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 2923 DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set"); 2924 } 2925 2926 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2927 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 2928 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 2929 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 2930 2931 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 2932 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format); 2933 return false; 2934 } 2935 2936 return true; 2937 } 2938 2939 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) 2940 { 2941 DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); 2942 2943 if (intra_vop_refresh == OMX_TRUE) { 2944 struct v4l2_control control; 2945 int rc; 2946 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME; 2947 control.value = 1; 2948 printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); 2949 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2950 2951 if (rc) { 2952 printf("Failed to set Intra Frame Request control\n"); 2953 return false; 2954 } 2955 2956 printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); 2957 } else { 2958 DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect"); 2959 } 2960 2961 return true; 2962 } 2963 2964 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) 2965 { 2966 bool status = true; 2967 struct v4l2_control control; 2968 int rc = 0; 2969 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL; 2970 2971 switch (eControlRate) { 2972 case OMX_Video_ControlRateDisable: 2973 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF; 2974 break; 2975 case OMX_Video_ControlRateVariableSkipFrames: 2976 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR; 2977 break; 2978 case OMX_Video_ControlRateVariable: 2979 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR; 2980 break; 2981 case OMX_Video_ControlRateConstantSkipFrames: 2982 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR; 2983 break; 2984 case OMX_Video_ControlRateConstant: 2985 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR; 2986 break; 2987 default: 2988 status = false; 2989 break; 2990 } 2991 2992 if (status) { 2993 2994 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); 2995 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2996 2997 if (rc) { 2998 DEBUG_PRINT_ERROR("Failed to set control\n"); 2999 return false; 3000 } 3001 3002 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); 3003 3004 rate_ctrl.rcmode = control.value; 3005 } 3006 3007 return status; 3008 } 3009 3010 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) 3011 { 3012 bool status = true; 3013 3014 if (eProfile == NULL || eLevel == NULL) { 3015 return false; 3016 } 3017 3018 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 3019 switch (codec_profile.profile) { 3020 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 3021 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 3022 break; 3023 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 3024 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 3025 break; 3026 default: 3027 *eProfile = OMX_VIDEO_MPEG4ProfileMax; 3028 status = false; 3029 break; 3030 } 3031 3032 if (!status) { 3033 return status; 3034 } 3035 3036 //profile level 3037 switch (profile_level.level) { 3038 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: 3039 *eLevel = OMX_VIDEO_MPEG4Level0; 3040 break; 3041 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: 3042 *eLevel = OMX_VIDEO_MPEG4Level0b; 3043 break; 3044 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: 3045 *eLevel = OMX_VIDEO_MPEG4Level1; 3046 break; 3047 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: 3048 *eLevel = OMX_VIDEO_MPEG4Level2; 3049 break; 3050 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: 3051 *eLevel = OMX_VIDEO_MPEG4Level3; 3052 break; 3053 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: 3054 *eLevel = OMX_VIDEO_MPEG4Level4; 3055 break; 3056 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: 3057 *eLevel = OMX_VIDEO_MPEG4Level5; 3058 break; 3059 default: 3060 *eLevel = OMX_VIDEO_MPEG4LevelMax; 3061 status = false; 3062 break; 3063 } 3064 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 3065 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) { 3066 *eProfile = OMX_VIDEO_H263ProfileBaseline; 3067 } else { 3068 *eProfile = OMX_VIDEO_H263ProfileMax; 3069 return false; 3070 } 3071 3072 switch (profile_level.level) { 3073 case VEN_LEVEL_H263_10: 3074 *eLevel = OMX_VIDEO_H263Level10; 3075 break; 3076 case VEN_LEVEL_H263_20: 3077 *eLevel = OMX_VIDEO_H263Level20; 3078 break; 3079 case VEN_LEVEL_H263_30: 3080 *eLevel = OMX_VIDEO_H263Level30; 3081 break; 3082 case VEN_LEVEL_H263_40: 3083 *eLevel = OMX_VIDEO_H263Level40; 3084 break; 3085 case VEN_LEVEL_H263_45: 3086 *eLevel = OMX_VIDEO_H263Level45; 3087 break; 3088 case VEN_LEVEL_H263_50: 3089 *eLevel = OMX_VIDEO_H263Level50; 3090 break; 3091 case VEN_LEVEL_H263_60: 3092 *eLevel = OMX_VIDEO_H263Level60; 3093 break; 3094 case VEN_LEVEL_H263_70: 3095 *eLevel = OMX_VIDEO_H263Level70; 3096 break; 3097 default: 3098 *eLevel = OMX_VIDEO_H263LevelMax; 3099 status = false; 3100 break; 3101 } 3102 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 3103 switch (codec_profile.profile) { 3104 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 3105 *eProfile = OMX_VIDEO_AVCProfileBaseline; 3106 break; 3107 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 3108 *eProfile = OMX_VIDEO_AVCProfileMain; 3109 break; 3110 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 3111 *eProfile = OMX_VIDEO_AVCProfileHigh; 3112 break; 3113 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 3114 *eProfile = OMX_VIDEO_AVCProfileExtended; 3115 break; 3116 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 3117 *eProfile = OMX_VIDEO_AVCProfileHigh10; 3118 break; 3119 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 3120 *eProfile = OMX_VIDEO_AVCProfileHigh422; 3121 break; 3122 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 3123 *eProfile = OMX_VIDEO_AVCProfileHigh444; 3124 break; 3125 default: 3126 *eProfile = OMX_VIDEO_AVCProfileMax; 3127 status = false; 3128 break; 3129 } 3130 3131 if (!status) { 3132 return status; 3133 } 3134 3135 switch (profile_level.level) { 3136 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 3137 *eLevel = OMX_VIDEO_AVCLevel1; 3138 break; 3139 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 3140 *eLevel = OMX_VIDEO_AVCLevel1b; 3141 break; 3142 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 3143 *eLevel = OMX_VIDEO_AVCLevel11; 3144 break; 3145 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 3146 *eLevel = OMX_VIDEO_AVCLevel12; 3147 break; 3148 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 3149 *eLevel = OMX_VIDEO_AVCLevel13; 3150 break; 3151 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 3152 *eLevel = OMX_VIDEO_AVCLevel2; 3153 break; 3154 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 3155 *eLevel = OMX_VIDEO_AVCLevel21; 3156 break; 3157 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 3158 *eLevel = OMX_VIDEO_AVCLevel22; 3159 break; 3160 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 3161 *eLevel = OMX_VIDEO_AVCLevel3; 3162 break; 3163 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 3164 *eLevel = OMX_VIDEO_AVCLevel31; 3165 break; 3166 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 3167 *eLevel = OMX_VIDEO_AVCLevel32; 3168 break; 3169 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 3170 *eLevel = OMX_VIDEO_AVCLevel4; 3171 break; 3172 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 3173 *eLevel = OMX_VIDEO_AVCLevel41; 3174 break; 3175 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 3176 *eLevel = OMX_VIDEO_AVCLevel42; 3177 break; 3178 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 3179 *eLevel = OMX_VIDEO_AVCLevel5; 3180 break; 3181 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 3182 *eLevel = OMX_VIDEO_AVCLevel51; 3183 break; 3184 default : 3185 *eLevel = OMX_VIDEO_AVCLevelMax; 3186 status = false; 3187 break; 3188 } 3189 } 3190 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 3191 switch (codec_profile.profile) { 3192 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: 3193 *eProfile = OMX_VIDEO_VP8ProfileMain; 3194 break; 3195 default: 3196 *eProfile = OMX_VIDEO_VP8ProfileMax; 3197 status = false; 3198 break; 3199 } 3200 if (!status) { 3201 return status; 3202 } 3203 3204 switch (profile_level.level) { 3205 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: 3206 *eLevel = OMX_VIDEO_VP8Level_Version0; 3207 break; 3208 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: 3209 *eLevel = OMX_VIDEO_VP8Level_Version1; 3210 break; 3211 default: 3212 *eLevel = OMX_VIDEO_VP8LevelMax; 3213 status = false; 3214 break; 3215 } 3216 } 3217 3218 return status; 3219 } 3220 3221 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) 3222 { 3223 OMX_U32 new_profile = 0, new_level = 0; 3224 unsigned const int *profile_tbl = NULL; 3225 OMX_U32 mb_per_frame, mb_per_sec; 3226 bool profile_level_found = false; 3227 3228 DEBUG_PRINT_LOW("\n Init profile table for respective codec"); 3229 3230 //validate the ht,width,fps,bitrate and set the appropriate profile and level 3231 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 3232 if (*eProfile == 0) { 3233 if (!m_profile_set) { 3234 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 3235 } else { 3236 switch (codec_profile.profile) { 3237 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 3238 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 3239 break; 3240 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 3241 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 3242 break; 3243 default: 3244 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); 3245 return false; 3246 } 3247 } 3248 } 3249 3250 if (*eLevel == 0 && !m_level_set) { 3251 *eLevel = OMX_VIDEO_MPEG4LevelMax; 3252 } 3253 3254 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 3255 profile_tbl = (unsigned int const *)mpeg4_profile_level_table; 3256 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 3257 profile_tbl = (unsigned int const *) 3258 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 3259 } else { 3260 DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile); 3261 return false; 3262 } 3263 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 3264 if (*eProfile == 0) { 3265 if (!m_profile_set) { 3266 *eProfile = OMX_VIDEO_AVCProfileBaseline; 3267 } else { 3268 switch (codec_profile.profile) { 3269 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 3270 *eProfile = OMX_VIDEO_AVCProfileBaseline; 3271 break; 3272 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 3273 *eProfile = OMX_VIDEO_AVCProfileMain; 3274 break; 3275 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 3276 *eProfile = OMX_VIDEO_AVCProfileExtended; 3277 break; 3278 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 3279 *eProfile = OMX_VIDEO_AVCProfileHigh; 3280 break; 3281 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 3282 *eProfile = OMX_VIDEO_AVCProfileHigh10; 3283 break; 3284 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 3285 *eProfile = OMX_VIDEO_AVCProfileHigh422; 3286 break; 3287 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 3288 *eProfile = OMX_VIDEO_AVCProfileHigh444; 3289 break; 3290 default: 3291 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); 3292 return false; 3293 } 3294 } 3295 } 3296 3297 if (*eLevel == 0 && !m_level_set) { 3298 *eLevel = OMX_VIDEO_AVCLevelMax; 3299 } 3300 3301 if (*eProfile == OMX_VIDEO_AVCProfileBaseline) { 3302 profile_tbl = (unsigned int const *)h264_profile_level_table; 3303 } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) { 3304 profile_tbl = (unsigned int const *) 3305 (&h264_profile_level_table[H264_HP_START]); 3306 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) { 3307 profile_tbl = (unsigned int const *) 3308 (&h264_profile_level_table[H264_MP_START]); 3309 } else { 3310 DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile); 3311 return false; 3312 } 3313 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 3314 if (*eProfile == 0) { 3315 if (!m_profile_set) { 3316 *eProfile = OMX_VIDEO_H263ProfileBaseline; 3317 } else { 3318 switch (codec_profile.profile) { 3319 case VEN_PROFILE_H263_BASELINE: 3320 *eProfile = OMX_VIDEO_H263ProfileBaseline; 3321 break; 3322 default: 3323 DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); 3324 return false; 3325 } 3326 } 3327 } 3328 3329 if (*eLevel == 0 && !m_level_set) { 3330 *eLevel = OMX_VIDEO_H263LevelMax; 3331 } 3332 3333 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) { 3334 profile_tbl = (unsigned int const *)h263_profile_level_table; 3335 } else { 3336 DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile); 3337 return false; 3338 } 3339 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 3340 if (*eProfile == 0) { 3341 *eProfile = OMX_VIDEO_VP8ProfileMain; 3342 } else { 3343 switch (codec_profile.profile) { 3344 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: 3345 *eProfile = OMX_VIDEO_VP8ProfileMain; 3346 break; 3347 default: 3348 DEBUG_PRINT_ERROR("\n %s(): Unknown VP8 profile", __func__); 3349 return false; 3350 } 3351 } 3352 if (*eLevel == 0) { 3353 switch (profile_level.level) { 3354 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: 3355 *eLevel = OMX_VIDEO_VP8Level_Version0; 3356 break; 3357 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: 3358 *eLevel = OMX_VIDEO_VP8Level_Version1; 3359 break; 3360 default: 3361 DEBUG_PRINT_ERROR("\n %s(): Unknown VP8 level", __func__); 3362 return false; 3363 } 3364 } 3365 return true; 3366 } else { 3367 DEBUG_PRINT_LOW("\n Invalid codec type"); 3368 return false; 3369 } 3370 3371 mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* 3372 ((m_sVenc_cfg.input_width + 15)>> 4); 3373 3374 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) { 3375 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) 3376 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 3377 3378 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) 3379 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 3380 3381 { 3382 new_level = profile_level.level; 3383 new_profile = codec_profile.profile; 3384 return true; 3385 } 3386 } 3387 3388 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; 3389 3390 do { 3391 if (mb_per_frame <= (unsigned int)profile_tbl[0]) { 3392 if (mb_per_sec <= (unsigned int)profile_tbl[1]) { 3393 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) { 3394 new_level = (int)profile_tbl[3]; 3395 new_profile = (int)profile_tbl[4]; 3396 profile_level_found = true; 3397 DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level); 3398 break; 3399 } 3400 } 3401 } 3402 3403 profile_tbl = profile_tbl + 5; 3404 } while (profile_tbl[0] != 0); 3405 3406 if (profile_level_found != true) { 3407 DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n"); 3408 return false; 3409 } 3410 3411 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) 3412 || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) { 3413 *eLevel = new_level; 3414 } 3415 3416 DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu\n" 3417 "Level = %lu", __func__, *eProfile, *eLevel); 3418 3419 return true; 3420 } 3421 #ifdef _ANDROID_ICS_ 3422 bool venc_dev::venc_set_meta_mode(bool mode) 3423 { 3424 metadatamode = 1; 3425 return true; 3426 } 3427 #endif 3428 3429 bool venc_dev::venc_is_video_session_supported(unsigned long width, 3430 unsigned long height) 3431 { 3432 if ((width * height < capability.min_width * capability.min_height) || 3433 (width * height > capability.max_width * capability.max_height)) { 3434 DEBUG_PRINT_ERROR( 3435 "Unsupported video resolution WxH = (%d)x(%d) supported range = min (%d)x(%d) - max (%d)x(%d)\n", 3436 width, height, capability.min_width, capability.min_height, 3437 capability.max_width, capability.max_height); 3438 return false; 3439 } 3440 3441 DEBUG_PRINT_LOW("\n video session supported\n"); 3442 return true; 3443 } 3444