1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010-2014, 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 <media/msm_vidc.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 #include <media/hardware/HardwareAPI.h> 43 44 #ifdef _ANDROID_ 45 #include <media/hardware/HardwareAPI.h> 46 #include <gralloc_priv.h> 47 #endif 48 49 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1)) 50 #define EXTRADATA_IDX(__num_planes) (__num_planes - 1) 51 52 #define MPEG4_SP_START 0 53 #define MPEG4_ASP_START (MPEG4_SP_START + 10) 54 #define H263_BP_START 0 55 #define H264_BP_START 0 56 #define H264_HP_START (H264_BP_START + 17) 57 #define H264_MP_START (H264_BP_START + 34) 58 #define POLL_TIMEOUT 1000 59 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */ 60 61 #define SZ_4K 0x1000 62 #define SZ_1M 0x100000 63 64 /* MPEG4 profile and level table*/ 65 static const unsigned int mpeg4_profile_level_table[][5]= { 66 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 67 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, 68 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, 69 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, 70 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, 71 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, 72 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 73 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 74 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 75 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, 76 {0,0,0,0,0}, 77 78 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 79 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 80 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 81 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 82 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 83 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 84 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 85 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, 86 {0,0,0,0,0}, 87 }; 88 89 /* H264 profile and level table*/ 90 static const unsigned int h264_profile_level_table[][5]= { 91 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 92 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, 93 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, 94 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, 95 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, 96 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, 97 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, 98 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, 99 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, 100 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, 101 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, 102 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, 103 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, 104 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline}, 105 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline}, 106 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline}, 107 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline}, 108 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline}, 109 {0,0,0,0,0}, 110 111 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, 112 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, 113 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, 114 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, 115 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, 116 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, 117 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, 118 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, 119 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, 120 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, 121 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, 122 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, 123 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh}, 124 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh}, 125 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh}, 126 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh}, 127 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh}, 128 {0,0,0,0,0}, 129 130 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, 131 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, 132 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, 133 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, 134 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, 135 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, 136 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, 137 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, 138 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, 139 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, 140 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, 141 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, 142 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain}, 143 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain}, 144 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain}, 145 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain}, 146 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline}, 147 {0,0,0,0,0} 148 149 }; 150 151 /* H263 profile and level table*/ 152 static const unsigned int h263_profile_level_table[][5]= { 153 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 154 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, 155 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, 156 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, 157 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, 158 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, 159 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, 160 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, 161 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 162 {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 163 {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, 164 {0,0,0,0,0} 165 }; 166 167 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 168 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 169 170 #define BUFFER_LOG_LOC "/data/misc/media" 171 172 //constructor 173 venc_dev::venc_dev(class omx_venc *venc_class) 174 { 175 //nothing to do 176 int i = 0; 177 venc_handle = venc_class; 178 etb = ebd = ftb = fbd = 0; 179 180 for (i = 0; i < MAX_PORT; i++) 181 streaming[i] = false; 182 183 stopped = 1; 184 paused = false; 185 async_thread_created = false; 186 color_format = 0; 187 pthread_mutex_init(&pause_resume_mlock, NULL); 188 pthread_cond_init(&pause_resume_cond, NULL); 189 memset(&extradata_info, 0, sizeof(extradata_info)); 190 memset(&idrperiod, 0, sizeof(idrperiod)); 191 memset(&multislice, 0, sizeof(multislice)); 192 memset (&slice_mode, 0 , sizeof(slice_mode)); 193 memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg)); 194 memset(&rate_ctrl, 0, sizeof(rate_ctrl)); 195 memset(&bitrate, 0, sizeof(bitrate)); 196 memset(&intra_period, 0, sizeof(intra_period)); 197 memset(&codec_profile, 0, sizeof(codec_profile)); 198 memset(&set_param, 0, sizeof(set_param)); 199 memset(&time_inc, 0, sizeof(time_inc)); 200 memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property)); 201 memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property)); 202 memset(&session_qp, 0, sizeof(session_qp)); 203 memset(&entropy, 0, sizeof(entropy)); 204 memset(&dbkfilter, 0, sizeof(dbkfilter)); 205 memset(&intra_refresh, 0, sizeof(intra_refresh)); 206 memset(&hec, 0, sizeof(hec)); 207 memset(&voptimecfg, 0, sizeof(voptimecfg)); 208 memset(&capability, 0, sizeof(capability)); 209 memset(&m_debug,0,sizeof(m_debug)); 210 memset(&hier_p_layers,0,sizeof(hier_p_layers)); 211 memset(&display_info,0,sizeof(display_info)); 212 is_searchrange_set = false; 213 enable_mv_narrow_searchrange = false; 214 215 char property_value[PROPERTY_VALUE_MAX] = {0}; 216 property_get("vidc.enc.log.in", property_value, "0"); 217 m_debug.in_buffer_log = atoi(property_value); 218 219 property_get("vidc.enc.log.out", property_value, "0"); 220 m_debug.out_buffer_log = atoi(property_value); 221 222 property_get("vidc.enc.log.extradata", property_value, "0"); 223 m_debug.extradata_log = atoi(property_value); 224 225 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, 226 "%s", BUFFER_LOG_LOC); 227 } 228 229 venc_dev::~venc_dev() 230 { 231 //nothing to do 232 } 233 234 void* venc_dev::async_venc_message_thread (void *input) 235 { 236 struct venc_msg venc_msg; 237 omx_video* omx_venc_base = NULL; 238 omx_venc *omx = reinterpret_cast<omx_venc*>(input); 239 omx_venc_base = reinterpret_cast<omx_video*>(input); 240 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 241 242 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); 243 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 244 struct pollfd pfd; 245 struct v4l2_buffer v4l2_buf; 246 struct v4l2_event dqevent; 247 pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 248 pfd.fd = omx->handle->m_nDriver_fd; 249 int error_code = 0,rc=0; 250 251 memset(&v4l2_buf, 0, sizeof(v4l2_buf)); 252 253 while (1) { 254 pthread_mutex_lock(&omx->handle->pause_resume_mlock); 255 256 if (omx->handle->paused) { 257 venc_msg.msgcode = VEN_MSG_PAUSE; 258 venc_msg.statuscode = VEN_S_SUCCESS; 259 260 if (omx->async_message_process(input, &venc_msg) < 0) { 261 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg"); 262 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 263 break; 264 } 265 266 /* Block here until the IL client resumes us again */ 267 pthread_cond_wait(&omx->handle->pause_resume_cond, 268 &omx->handle->pause_resume_mlock); 269 270 venc_msg.msgcode = VEN_MSG_RESUME; 271 venc_msg.statuscode = VEN_S_SUCCESS; 272 273 if (omx->async_message_process(input, &venc_msg) < 0) { 274 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg"); 275 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 276 break; 277 } 278 } 279 280 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 281 282 rc = poll(&pfd, 1, POLL_TIMEOUT); 283 284 if (!rc) { 285 DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d", 286 omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd); 287 continue; 288 } else if (rc < 0) { 289 DEBUG_PRINT_ERROR("Error while polling: %d", rc); 290 break; 291 } 292 293 if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { 294 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 295 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 296 v4l2_buf.length = omx->handle->num_planes; 297 v4l2_buf.m.planes = plane; 298 299 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { 300 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE; 301 venc_msg.statuscode=VEN_S_SUCCESS; 302 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index; 303 venc_msg.buf.len= v4l2_buf.m.planes->bytesused; 304 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset; 305 venc_msg.buf.flags = 0; 306 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer; 307 venc_msg.buf.clientdata=(void*)omxhdr; 308 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec; 309 310 /* TODO: ideally report other types of frames as well 311 * for now it doesn't look like IL client cares about 312 * other types 313 */ 314 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) 315 venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR; 316 317 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) 318 venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME; 319 320 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG) 321 venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG; 322 323 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS) 324 venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS; 325 326 if (omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused) 327 venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA; 328 329 if (omxhdr->nFilledLen) 330 venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME; 331 332 omx->handle->fbd++; 333 334 if (omx->async_message_process(input,&venc_msg) < 0) { 335 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 336 break; 337 } 338 } 339 } 340 341 if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { 342 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 343 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 344 v4l2_buf.m.planes = plane; 345 v4l2_buf.length = 1; 346 347 while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { 348 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE; 349 venc_msg.statuscode=VEN_S_SUCCESS; 350 omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index; 351 venc_msg.buf.clientdata=(void*)omxhdr; 352 omx->handle->ebd++; 353 354 if (omx->async_message_process(input,&venc_msg) < 0) { 355 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 356 break; 357 } 358 } 359 } 360 361 if (pfd.revents & POLLPRI) { 362 rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); 363 364 if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { 365 DEBUG_PRINT_HIGH("CLOSE DONE"); 366 break; 367 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 368 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE; 369 venc_msg.statuscode = VEN_S_SUCCESS; 370 371 if (omx->async_message_process(input,&venc_msg) < 0) { 372 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 373 break; 374 } 375 376 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE; 377 venc_msg.statuscode = VEN_S_SUCCESS; 378 379 if (omx->async_message_process(input,&venc_msg) < 0) { 380 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 381 break; 382 } 383 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { 384 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state"); 385 venc_msg.msgcode = VEN_MSG_INDICATION; 386 venc_msg.statuscode=VEN_S_EFAIL; 387 388 if (omx->async_message_process(input,&venc_msg) < 0) { 389 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 390 break; 391 } 392 } 393 } 394 } 395 396 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit"); 397 return NULL; 398 } 399 400 static const int event_type[] = { 401 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 402 V4L2_EVENT_MSM_VIDC_CLOSE_DONE, 403 V4L2_EVENT_MSM_VIDC_SYS_ERROR 404 }; 405 406 static OMX_ERRORTYPE subscribe_to_events(int fd) 407 { 408 OMX_ERRORTYPE eRet = OMX_ErrorNone; 409 struct v4l2_event_subscription sub; 410 int array_sz = sizeof(event_type)/sizeof(int); 411 int i,rc; 412 memset(&sub, 0, sizeof(sub)); 413 414 if (fd < 0) { 415 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 416 return OMX_ErrorBadParameter; 417 } 418 419 for (i = 0; i < array_sz; ++i) { 420 memset(&sub, 0, sizeof(sub)); 421 sub.type = event_type[i]; 422 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 423 424 if (rc) { 425 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type); 426 break; 427 } 428 } 429 430 if (i < array_sz) { 431 for (--i; i >=0 ; i--) { 432 memset(&sub, 0, sizeof(sub)); 433 sub.type = event_type[i]; 434 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 435 436 if (rc) 437 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 438 } 439 440 eRet = OMX_ErrorNotImplemented; 441 } 442 443 return eRet; 444 } 445 446 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src) 447 { 448 OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst; 449 450 if (!dst || !src) 451 return 0; 452 453 /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those 454 * targets, since the payload format will be different */ 455 mbi->nFormat = 1; 456 mbi->nDataSize = src->data_size; 457 memcpy(&mbi->data, &src->data, src->data_size); 458 459 return mbi->nDataSize + sizeof(*mbi); 460 } 461 462 bool venc_dev::handle_extradata(void *buffer, int index) 463 { 464 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer; 465 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 466 467 if (!extradata_info.uaddr) { 468 DEBUG_PRINT_ERROR("Extradata buffers not allocated"); 469 return false; 470 } 471 472 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer + 473 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4); 474 475 if (extradata_info.buffer_size > 476 p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) { 477 DEBUG_PRINT_ERROR("Insufficient buffer size for extradata"); 478 p_extra = NULL; 479 return false; 480 } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) { 481 /* A lot of the code below assumes this condition, so error out if it's not met */ 482 DEBUG_PRINT_ERROR("Extradata ABI mismatch"); 483 return false; 484 } 485 486 struct msm_vidc_extradata_header *p_extradata = NULL; 487 do { 488 p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ? 489 ((char *)p_extradata) + p_extradata->size : 490 extradata_info.uaddr + index * extradata_info.buffer_size); 491 492 switch (p_extradata->type) { 493 case MSM_VIDC_EXTRADATA_METADATA_MBI: 494 { 495 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata); 496 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4); 497 p_extra->nVersion.nVersion = OMX_SPEC_VERSION; 498 p_extra->nPortIndex = OMX_DirOutput; 499 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo; 500 p_extra->nDataSize = payloadSize; 501 break; 502 } 503 case MSM_VIDC_EXTRADATA_NONE: 504 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4); 505 p_extra->nVersion.nVersion = OMX_SPEC_VERSION; 506 p_extra->nPortIndex = OMX_DirOutput; 507 p_extra->eType = OMX_ExtraDataNone; 508 p_extra->nDataSize = 0; 509 break; 510 default: 511 /* No idea what this stuff is, just skip over it */ 512 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it", 513 p_extradata->type); 514 continue; 515 } 516 517 p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize); 518 } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE); 519 520 /* Just for debugging: Traverse the list of extra datas and spit it out onto log */ 521 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer + 522 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4); 523 while(p_extra->eType != OMX_ExtraDataNone) 524 { 525 DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p", 526 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType, 527 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra); 528 529 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + 530 p_extra->nSize); 531 } 532 533 return true; 534 } 535 536 int venc_dev::venc_set_format(int format) 537 { 538 int rc = true; 539 540 if (format) 541 color_format = format; 542 else { 543 color_format = 0; 544 rc = false; 545 } 546 547 return rc; 548 } 549 550 OMX_ERRORTYPE venc_dev::allocate_extradata() 551 { 552 if (extradata_info.allocated) { 553 DEBUG_PRINT_ERROR("Extradata already allocated!"); 554 return OMX_ErrorNone; 555 } 556 557 #ifdef USE_ION 558 559 if (extradata_info.buffer_size) { 560 if (extradata_info.ion.ion_alloc_data.handle) { 561 munmap((void *)extradata_info.uaddr, extradata_info.size); 562 close(extradata_info.ion.fd_ion_data.fd); 563 venc_handle->free_ion_memory(&extradata_info.ion); 564 } 565 566 extradata_info.size = ALIGN(extradata_info.size, SZ_4K); 567 568 extradata_info.ion.ion_device_fd = venc_handle->alloc_map_ion_memory( 569 extradata_info.size, 570 &extradata_info.ion.ion_alloc_data, 571 &extradata_info.ion.fd_ion_data, 0); 572 573 if (extradata_info.ion.ion_device_fd < 0) { 574 DEBUG_PRINT_ERROR("Failed to alloc extradata memory"); 575 return OMX_ErrorInsufficientResources; 576 } 577 578 extradata_info.uaddr = (char *)mmap(NULL, 579 extradata_info.size, 580 PROT_READ|PROT_WRITE, MAP_SHARED, 581 extradata_info.ion.fd_ion_data.fd , 0); 582 583 if (extradata_info.uaddr == MAP_FAILED) { 584 DEBUG_PRINT_ERROR("Failed to map extradata memory"); 585 close(extradata_info.ion.fd_ion_data.fd); 586 venc_handle->free_ion_memory(&extradata_info.ion); 587 return OMX_ErrorInsufficientResources; 588 } 589 } 590 591 #endif 592 extradata_info.allocated = 1; 593 return OMX_ErrorNone; 594 } 595 596 void venc_dev::free_extradata() 597 { 598 #ifdef USE_ION 599 600 if (extradata_info.uaddr) { 601 munmap((void *)extradata_info.uaddr, extradata_info.size); 602 close(extradata_info.ion.fd_ion_data.fd); 603 venc_handle->free_ion_memory(&extradata_info.ion); 604 } 605 606 memset(&extradata_info, 0, sizeof(extradata_info)); 607 #endif 608 } 609 610 bool venc_dev::venc_get_output_log_flag() 611 { 612 return (m_debug.out_buffer_log == 1); 613 } 614 615 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len) 616 { 617 if (!m_debug.outfile) { 618 int size = 0; 619 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 620 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v", 621 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 622 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 623 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264", 624 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 625 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 626 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263", 627 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 628 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 629 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf", 630 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 631 } 632 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 633 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d", 634 m_debug.outfile_name, size); 635 } 636 m_debug.outfile = fopen(m_debug.outfile_name, "ab"); 637 if (!m_debug.outfile) { 638 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d", 639 m_debug.outfile_name, errno); 640 m_debug.outfile_name[0] = '\0'; 641 return -1; 642 } 643 } 644 if (m_debug.outfile && buffer_len) { 645 DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len); 646 fwrite(buffer_addr, buffer_len, 1, m_debug.outfile); 647 } 648 return 0; 649 } 650 651 int venc_dev::venc_extradata_log_buffers(char *buffer_addr) 652 { 653 if (!m_debug.extradatafile && m_debug.extradata_log) { 654 int size = 0; 655 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 656 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v", 657 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 658 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 659 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264", 660 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 661 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 662 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263", 663 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 664 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 665 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf", 666 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 667 } 668 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 669 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d", 670 m_debug.extradatafile_name, size); 671 } 672 673 m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab"); 674 if (!m_debug.extradatafile) { 675 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d", 676 m_debug.extradatafile_name, errno); 677 m_debug.extradatafile_name[0] = '\0'; 678 return -1; 679 } 680 } 681 682 if (m_debug.extradatafile) { 683 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 684 do { 685 p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr : 686 ((char *)p_extra) + p_extra->nSize); 687 fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile); 688 } while (p_extra->eType != OMX_ExtraDataNone); 689 } 690 return 0; 691 } 692 693 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset) { 694 if (!m_debug.infile) { 695 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv", 696 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 697 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 698 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d", 699 m_debug.infile_name, size); 700 } 701 m_debug.infile = fopen (m_debug.infile_name, "ab"); 702 if (!m_debug.infile) { 703 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name); 704 m_debug.infile_name[0] = '\0'; 705 return -1; 706 } 707 } 708 if (m_debug.infile && pbuffer && pbuffer->nFilledLen) { 709 unsigned long i, msize; 710 int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width); 711 int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height); 712 unsigned char *pvirt,*ptemp; 713 714 char *temp = (char *)pbuffer->pBuffer; 715 716 msize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height); 717 if (metadatamode == 1) { 718 pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset); 719 if (pvirt) { 720 ptemp = pvirt; 721 for (i = 0; i < m_sVenc_cfg.input_height; i++) { 722 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile); 723 ptemp += stride; 724 } 725 ptemp = pvirt + (stride * scanlines); 726 for(i = 0; i < m_sVenc_cfg.input_height/2; i++) { 727 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile); 728 ptemp += stride; 729 } 730 munmap(pvirt, msize); 731 } else if (pvirt == MAP_FAILED) { 732 DEBUG_PRINT_ERROR("%s mmap failed", __func__); 733 return -1; 734 } 735 } else { 736 for (i = 0; i < m_sVenc_cfg.input_height; i++) { 737 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile); 738 temp += stride; 739 } 740 741 temp = (char *)pbuffer->pBuffer + (stride * scanlines); 742 743 for(i = 0; i < m_sVenc_cfg.input_height/2; i++) { 744 fwrite(temp, m_sVenc_cfg.input_width, 1, m_debug.infile); 745 temp += stride; 746 } 747 } 748 } 749 return 0; 750 } 751 752 bool venc_dev::venc_open(OMX_U32 codec) 753 { 754 int r; 755 unsigned int alignment = 0,buffer_size = 0, temp =0; 756 struct v4l2_control control; 757 OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc"; 758 759 char platform_name[PROPERTY_VALUE_MAX]; 760 property_get("ro.board.platform", platform_name, "0"); 761 762 if (!strncmp(platform_name, "msm8610", 7)) { 763 device_name = (OMX_STRING)"/dev/video/q6_enc"; 764 } 765 if (!strncmp(platform_name, "msm8916", 7)) { 766 enable_mv_narrow_searchrange = true; 767 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( 768 ISurfaceComposer::eDisplayIdMain)); 769 SurfaceComposerClient::getDisplayInfo(display, &display_info); 770 DEBUG_PRINT_LOW("Display panel resolution %dX%d", 771 display_info.w, display_info.h); 772 } 773 m_nDriver_fd = open (device_name, O_RDWR); 774 775 if (m_nDriver_fd == 0) { 776 DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again"); 777 m_nDriver_fd = open (device_name, O_RDWR); 778 } 779 780 if ((int)m_nDriver_fd < 0) { 781 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure"); 782 return false; 783 } 784 785 DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd); 786 // set the basic configuration of the video encoder driver 787 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; 788 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; 789 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; 790 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; 791 m_sVenc_cfg.fps_num = 30; 792 m_sVenc_cfg.fps_den = 1; 793 m_sVenc_cfg.targetbitrate = 64000; 794 m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12; 795 m_codec = codec; 796 797 if (codec == OMX_VIDEO_CodingMPEG4) { 798 m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4; 799 codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; 800 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; 801 session_qp_range.minqp = 1; 802 session_qp_range.maxqp = 31; 803 } else if (codec == OMX_VIDEO_CodingH263) { 804 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263; 805 codec_profile.profile = VEN_PROFILE_H263_BASELINE; 806 profile_level.level = VEN_LEVEL_H263_20; 807 session_qp_range.minqp = 1; 808 session_qp_range.maxqp = 31; 809 } else if (codec == OMX_VIDEO_CodingAVC) { 810 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264; 811 codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; 812 profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; 813 session_qp_range.minqp = 1; 814 session_qp_range.maxqp = 51; 815 } else if (codec == OMX_VIDEO_CodingVP8) { 816 m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8; 817 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; 818 profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; 819 session_qp_range.minqp = 1; 820 session_qp_range.maxqp = 128; 821 } 822 session_qp_values.minqp = session_qp_range.minqp; 823 session_qp_values.maxqp = session_qp_range.maxqp; 824 825 int ret; 826 ret = subscribe_to_events(m_nDriver_fd); 827 828 if (ret) { 829 DEBUG_PRINT_ERROR("Subscribe Event Failed"); 830 return false; 831 } 832 833 struct v4l2_capability cap; 834 835 struct v4l2_fmtdesc fdesc; 836 837 struct v4l2_format fmt; 838 839 struct v4l2_requestbuffers bufreq; 840 841 ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap); 842 843 if (ret) { 844 DEBUG_PRINT_ERROR("Failed to query capabilities"); 845 } else { 846 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," 847 " version = %d, capabilities = %x", cap.driver, cap.card, 848 cap.bus_info, cap.version, cap.capabilities); 849 } 850 851 ret=0; 852 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 853 fdesc.index=0; 854 855 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 856 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 857 fdesc.pixelformat, fdesc.flags); 858 fdesc.index++; 859 } 860 861 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 862 fdesc.index=0; 863 864 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 865 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 866 fdesc.pixelformat, fdesc.flags); 867 fdesc.index++; 868 } 869 870 if (venc_handle->is_secure_session()) { 871 m_sOutput_buff_property.alignment = SZ_1M; 872 m_sInput_buff_property.alignment = SZ_1M; 873 } else { 874 m_sOutput_buff_property.alignment = SZ_4K; 875 m_sInput_buff_property.alignment = SZ_4K; 876 } 877 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 878 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 879 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 880 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 881 882 /*TODO: Return values not handled properly in this function anywhere. 883 * Need to handle those.*/ 884 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 885 886 if (ret) { 887 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 888 return false; 889 } 890 891 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 892 893 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 894 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 895 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 896 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 897 898 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 899 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 900 901 bufreq.memory = V4L2_MEMORY_USERPTR; 902 bufreq.count = 2; 903 904 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 905 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 906 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 907 908 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 909 bufreq.count = 2; 910 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 911 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 912 913 if(venc_handle->is_secure_session()) { 914 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; 915 control.value = 1; 916 DEBUG_PRINT_HIGH("ioctl: open secure device"); 917 ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control); 918 if (ret) { 919 DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret); 920 return false; 921 } 922 } 923 924 resume_in_stopped = 0; 925 metadatamode = 0; 926 927 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; 928 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; 929 930 DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value); 931 932 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) 933 DEBUG_PRINT_ERROR("Failed to set control"); 934 935 struct v4l2_frmsizeenum frmsize; 936 937 //Get the hardware capabilities 938 memset((void *)&frmsize,0,sizeof(frmsize)); 939 frmsize.index = 0; 940 frmsize.pixel_format = m_sVenc_cfg.codectype; 941 ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize); 942 943 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { 944 DEBUG_PRINT_ERROR("Failed to get framesizes"); 945 return false; 946 } 947 948 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 949 capability.min_width = frmsize.stepwise.min_width; 950 capability.max_width = frmsize.stepwise.max_width; 951 capability.min_height = frmsize.stepwise.min_height; 952 capability.max_height = frmsize.stepwise.max_height; 953 } 954 //Initialize non-default parameters 955 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 956 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 957 control.value = 0x7fffffff; 958 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) 959 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n"); 960 } 961 962 return true; 963 } 964 965 966 static OMX_ERRORTYPE unsubscribe_to_events(int fd) 967 { 968 OMX_ERRORTYPE eRet = OMX_ErrorNone; 969 struct v4l2_event_subscription sub; 970 int array_sz = sizeof(event_type)/sizeof(int); 971 int i,rc; 972 973 if (fd < 0) { 974 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 975 return OMX_ErrorBadParameter; 976 } 977 978 for (i = 0; i < array_sz; ++i) { 979 memset(&sub, 0, sizeof(sub)); 980 sub.type = event_type[i]; 981 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 982 983 if (rc) { 984 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 985 break; 986 } 987 } 988 989 return eRet; 990 } 991 992 void venc_dev::venc_close() 993 { 994 struct v4l2_encoder_cmd enc; 995 DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd); 996 997 if ((int)m_nDriver_fd >= 0) { 998 enc.cmd = V4L2_ENC_CMD_STOP; 999 ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc); 1000 DEBUG_PRINT_HIGH("venc_close E"); 1001 1002 if (async_thread_created) 1003 pthread_join(m_tid,NULL); 1004 1005 DEBUG_PRINT_HIGH("venc_close X"); 1006 unsubscribe_to_events(m_nDriver_fd); 1007 close(m_nDriver_fd); 1008 m_nDriver_fd = -1; 1009 } 1010 1011 if (m_debug.infile) { 1012 fclose(m_debug.infile); 1013 m_debug.infile = NULL; 1014 } 1015 1016 if (m_debug.outfile) { 1017 fclose(m_debug.outfile); 1018 m_debug.outfile = NULL; 1019 } 1020 1021 if (m_debug.extradatafile) { 1022 fclose(m_debug.extradatafile); 1023 m_debug.extradatafile = NULL; 1024 } 1025 } 1026 1027 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count, 1028 OMX_U32 *actual_buff_count, 1029 OMX_U32 *buff_size, 1030 OMX_U32 port) 1031 { 1032 (void)min_buff_count, (void)buff_size; 1033 unsigned long temp_count = 0; 1034 1035 if (port == 0) { 1036 if (*actual_buff_count > m_sInput_buff_property.mincount) { 1037 temp_count = m_sInput_buff_property.actualcount; 1038 m_sInput_buff_property.actualcount = *actual_buff_count; 1039 DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count); 1040 } 1041 } else { 1042 if (*actual_buff_count > m_sOutput_buff_property.mincount) { 1043 temp_count = m_sOutput_buff_property.actualcount; 1044 m_sOutput_buff_property.actualcount = *actual_buff_count; 1045 DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count); 1046 } 1047 } 1048 1049 return true; 1050 1051 } 1052 1053 bool venc_dev::venc_loaded_start() 1054 { 1055 return true; 1056 } 1057 1058 bool venc_dev::venc_loaded_stop() 1059 { 1060 return true; 1061 } 1062 1063 bool venc_dev::venc_loaded_start_done() 1064 { 1065 return true; 1066 } 1067 1068 bool venc_dev::venc_loaded_stop_done() 1069 { 1070 return true; 1071 } 1072 1073 bool venc_dev::venc_get_seq_hdr(void *buffer, 1074 unsigned buffer_size, OMX_U32 *header_len) 1075 { 1076 (void) buffer, (void) buffer_size, (void) header_len; 1077 return true; 1078 } 1079 1080 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count, 1081 OMX_U32 *actual_buff_count, 1082 OMX_U32 *buff_size, 1083 OMX_U32 port) 1084 { 1085 struct v4l2_format fmt; 1086 struct v4l2_requestbuffers bufreq; 1087 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; 1088 int ret; 1089 1090 if (port == 0) { 1091 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1092 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 1093 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 1094 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 1095 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 1096 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1097 bufreq.memory = V4L2_MEMORY_USERPTR; 1098 1099 if (*actual_buff_count) 1100 bufreq.count = *actual_buff_count; 1101 else 1102 bufreq.count = 2; 1103 1104 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1105 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 1106 1107 if (ret) { 1108 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed"); 1109 return false; 1110 } 1111 1112 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 1113 *min_buff_count = m_sInput_buff_property.mincount; 1114 *actual_buff_count = m_sInput_buff_property.actualcount; 1115 #ifdef USE_ION 1116 // For ION memory allocations of the allocated buffer size 1117 // must be 4k aligned, hence aligning the input buffer 1118 // size to 4k. 1119 m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K); 1120 #endif 1121 *buff_size = m_sInput_buff_property.datasize; 1122 } else { 1123 int extra_idx = 0; 1124 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1125 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1126 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1127 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1128 1129 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 1130 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1131 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1132 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1133 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1134 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1135 1136 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 1137 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1138 bufreq.memory = V4L2_MEMORY_USERPTR; 1139 1140 if (*actual_buff_count) 1141 bufreq.count = *actual_buff_count; 1142 else 1143 bufreq.count = 2; 1144 1145 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1146 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 1147 1148 if (ret) { 1149 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed"); 1150 return false; 1151 } 1152 1153 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 1154 *min_buff_count = m_sOutput_buff_property.mincount; 1155 *actual_buff_count = m_sOutput_buff_property.actualcount; 1156 *buff_size = m_sOutput_buff_property.datasize; 1157 num_planes = fmt.fmt.pix_mp.num_planes; 1158 extra_idx = EXTRADATA_IDX(num_planes); 1159 1160 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 1161 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 1162 } else if (extra_idx >= VIDEO_MAX_PLANES) { 1163 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 1164 return OMX_ErrorBadParameter; 1165 } 1166 1167 extradata_info.buffer_size = extra_data_size; 1168 extradata_info.count = m_sOutput_buff_property.actualcount; 1169 extradata_info.size = extradata_info.buffer_size * extradata_info.count; 1170 } 1171 1172 return true; 1173 } 1174 1175 bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) 1176 { 1177 DEBUG_PRINT_LOW("venc_set_param:: venc-720p"); 1178 struct v4l2_format fmt; 1179 struct v4l2_requestbuffers bufreq; 1180 int ret; 1181 1182 switch ((int)index) { 1183 case OMX_IndexParamPortDefinition: 1184 { 1185 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 1186 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 1187 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition"); 1188 1189 if (portDefn->nPortIndex == PORT_INDEX_IN) { 1190 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) { 1191 return false; 1192 } 1193 1194 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) { 1195 return false; 1196 } 1197 if ((display_info.w * display_info.h) > (OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT) 1198 && enable_mv_narrow_searchrange && 1199 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >= 1200 (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) { 1201 if (venc_set_searchrange() == false) { 1202 DEBUG_PRINT_ERROR("ERROR: Failed to set search range"); 1203 } 1204 } 1205 if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight || 1206 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) { 1207 DEBUG_PRINT_LOW("Basic parameter has changed"); 1208 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; 1209 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; 1210 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1211 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 1212 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 1213 fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 1214 1215 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 1216 DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed"); 1217 return false; 1218 } 1219 1220 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1221 bufreq.memory = V4L2_MEMORY_USERPTR; 1222 bufreq.count = portDefn->nBufferCountActual; 1223 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1224 1225 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 1226 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed"); 1227 return false; 1228 } 1229 1230 if (bufreq.count == portDefn->nBufferCountActual) 1231 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 1232 1233 if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) 1234 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; 1235 } 1236 1237 DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u", 1238 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count); 1239 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) { 1240 m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight; 1241 m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth; 1242 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1243 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1244 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1245 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1246 1247 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 1248 DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed"); 1249 return false; 1250 } 1251 1252 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1253 1254 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) { 1255 return false; 1256 } 1257 1258 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 1259 bufreq.memory = V4L2_MEMORY_USERPTR; 1260 bufreq.count = portDefn->nBufferCountActual; 1261 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1262 1263 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 1264 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u", 1265 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount); 1266 return false; 1267 } 1268 1269 if (bufreq.count == portDefn->nBufferCountActual) 1270 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 1271 1272 if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) 1273 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 1274 1275 if (num_planes > 1) 1276 extradata_info.count = m_sOutput_buff_property.actualcount; 1277 1278 DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u", 1279 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count); 1280 } else { 1281 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); 1282 } 1283 1284 break; 1285 } 1286 case OMX_IndexParamVideoPortFormat: 1287 { 1288 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; 1289 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 1290 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat"); 1291 1292 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) { 1293 if (!venc_set_color_format(portFmt->eColorFormat)) { 1294 return false; 1295 } 1296 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1297 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) { 1298 return false; 1299 } 1300 } else { 1301 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); 1302 } 1303 1304 break; 1305 } 1306 case OMX_IndexParamVideoBitrate: 1307 { 1308 OMX_VIDEO_PARAM_BITRATETYPE* pParam; 1309 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 1310 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate"); 1311 1312 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1313 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) { 1314 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed"); 1315 return false; 1316 } 1317 1318 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) { 1319 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed"); 1320 return false; 1321 } 1322 } else { 1323 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); 1324 } 1325 1326 break; 1327 } 1328 case OMX_IndexParamVideoMpeg4: 1329 { 1330 OMX_VIDEO_PARAM_MPEG4TYPE* pParam; 1331 OMX_U32 bFrames = 0; 1332 1333 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 1334 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4"); 1335 1336 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1337 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) { 1338 DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed"); 1339 return false; 1340 } 1341 1342 m_profile_set = false; 1343 m_level_set = false; 1344 1345 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1346 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level"); 1347 return false; 1348 } else { 1349 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 1350 if (pParam->nBFrames) { 1351 bFrames = pParam->nBFrames; 1352 } 1353 } else { 1354 if (pParam->nBFrames) { 1355 DEBUG_PRINT_ERROR("Warning: B frames not supported"); 1356 bFrames = 0; 1357 } 1358 } 1359 } 1360 1361 if (!venc_set_intra_period (pParam->nPFrames,bFrames)) { 1362 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1363 return false; 1364 } 1365 1366 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) { 1367 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config"); 1368 return false; 1369 } 1370 } else { 1371 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); 1372 } 1373 1374 break; 1375 } 1376 case OMX_IndexParamVideoH263: 1377 { 1378 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 1379 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263"); 1380 OMX_U32 bFrames = 0; 1381 1382 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1383 m_profile_set = false; 1384 m_level_set = false; 1385 1386 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1387 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level"); 1388 return false; 1389 } 1390 1391 if (pParam->nBFrames) 1392 DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263"); 1393 1394 if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) { 1395 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1396 return false; 1397 } 1398 } else { 1399 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263"); 1400 } 1401 1402 break; 1403 } 1404 case OMX_IndexParamVideoAvc: 1405 { 1406 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc"); 1407 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 1408 OMX_U32 bFrames = 0; 1409 1410 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1411 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d", 1412 pParam->eProfile,pParam->eLevel); 1413 1414 m_profile_set = false; 1415 m_level_set = false; 1416 1417 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) { 1418 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d", 1419 pParam->eProfile, pParam->eLevel); 1420 return false; 1421 } else { 1422 if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) && 1423 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) { 1424 if (pParam->nBFrames) { 1425 bFrames = pParam->nBFrames; 1426 } 1427 } else { 1428 if (pParam->nBFrames) { 1429 DEBUG_PRINT_ERROR("Warning: B frames not supported"); 1430 bFrames = 0; 1431 } 1432 } 1433 } 1434 1435 if (!venc_set_intra_period (pParam->nPFrames, bFrames)) { 1436 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1437 return false; 1438 } 1439 1440 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) { 1441 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed"); 1442 return false; 1443 } 1444 1445 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) { 1446 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed"); 1447 return false; 1448 } 1449 1450 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) { 1451 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config"); 1452 return false; 1453 } 1454 } else { 1455 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); 1456 } 1457 1458 //TBD, lot of other variables to be updated, yet to decide 1459 break; 1460 } 1461 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8: 1462 { 1463 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8"); 1464 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData; 1465 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1466 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d", 1467 pParam->eProfile, pParam->eLevel); 1468 return false; 1469 } 1470 1471 if(!venc_set_ltrmode(1, 1)) { 1472 DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode"); 1473 return false; 1474 } 1475 1476 // For VP8, hier-p and ltr are mutually exclusive features in firmware 1477 // Disable hier-p if ltr is enabled. 1478 if (m_codec == OMX_VIDEO_CodingVP8) { 1479 DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set"); 1480 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) { 1481 DEBUG_PRINT_ERROR("Disabling Hier P count failed"); 1482 } 1483 } 1484 1485 break; 1486 } 1487 case OMX_IndexParamVideoIntraRefresh: 1488 { 1489 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh"); 1490 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = 1491 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; 1492 1493 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1494 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) { 1495 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 1496 return false; 1497 } 1498 } else { 1499 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); 1500 } 1501 1502 break; 1503 } 1504 case OMX_IndexParamVideoErrorCorrection: 1505 { 1506 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection"); 1507 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = 1508 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; 1509 1510 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1511 if (venc_set_error_resilience(error_resilience) == false) { 1512 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 1513 return false; 1514 } 1515 } else { 1516 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); 1517 } 1518 1519 break; 1520 } 1521 case OMX_IndexParamVideoProfileLevelCurrent: 1522 { 1523 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent"); 1524 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = 1525 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 1526 1527 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1528 m_profile_set = false; 1529 m_level_set = false; 1530 1531 if (!venc_set_profile_level (profile_level->eProfile, 1532 profile_level->eLevel)) { 1533 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level"); 1534 return false; 1535 } 1536 } else { 1537 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); 1538 } 1539 1540 break; 1541 } 1542 case OMX_IndexParamVideoQuantization: 1543 { 1544 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization"); 1545 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = 1546 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; 1547 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1548 if (venc_set_session_qp (session_qp->nQpI, 1549 session_qp->nQpP, 1550 session_qp->nQpB) == false) { 1551 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed"); 1552 return false; 1553 } 1554 } else { 1555 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); 1556 } 1557 1558 break; 1559 } 1560 case QOMX_IndexParamVideoInitialQp: 1561 { 1562 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp = 1563 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData; 1564 if (initqp->bEnableInitQp) { 1565 DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp); 1566 if(venc_enable_initial_qp(initqp) == false) { 1567 DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP"); 1568 return OMX_ErrorUnsupportedSetting; 1569 } 1570 } else 1571 DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp"); 1572 break; 1573 } 1574 case OMX_QcomIndexParamVideoQPRange: 1575 { 1576 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange"); 1577 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range = 1578 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData; 1579 1580 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1581 if(venc_set_session_qp_range (session_qp_range->minQP, 1582 session_qp_range->maxQP) == false) { 1583 DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed", 1584 (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP); 1585 return false; 1586 } else { 1587 session_qp_values.minqp = session_qp_range->minQP; 1588 session_qp_values.maxqp = session_qp_range->maxQP; 1589 } 1590 } else { 1591 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange"); 1592 } 1593 1594 break; 1595 } 1596 case OMX_QcomIndexEnableSliceDeliveryMode: 1597 { 1598 QOMX_EXTNINDEX_PARAMTYPE* pParam = 1599 (QOMX_EXTNINDEX_PARAMTYPE*)paramData; 1600 1601 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1602 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) { 1603 DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); 1604 return OMX_ErrorUnsupportedSetting; 1605 } 1606 } else { 1607 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " 1608 "called on wrong port(%u)", (unsigned int)pParam->nPortIndex); 1609 return OMX_ErrorBadPortIndex; 1610 } 1611 1612 break; 1613 } 1614 case OMX_ExtraDataVideoEncoderSliceInfo: 1615 { 1616 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); 1617 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData); 1618 1619 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) { 1620 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed"); 1621 return false; 1622 } 1623 1624 extradata = true; 1625 break; 1626 } 1627 case OMX_ExtraDataVideoEncoderMBInfo: 1628 { 1629 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo"); 1630 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData); 1631 1632 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) { 1633 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed"); 1634 return false; 1635 } 1636 1637 extradata = true; 1638 break; 1639 } 1640 case OMX_QcomIndexParamSequenceHeaderWithIDR: 1641 { 1642 PrependSPSPPSToIDRFramesParams * pParam = 1643 (PrependSPSPPSToIDRFramesParams *)paramData; 1644 1645 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable); 1646 if(venc_set_inband_video_header(pParam->bEnable) == false) { 1647 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed"); 1648 return OMX_ErrorUnsupportedSetting; 1649 } 1650 1651 break; 1652 } 1653 case OMX_QcomIndexParamH264AUDelimiter: 1654 { 1655 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam = 1656 (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData; 1657 1658 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable); 1659 if(venc_set_au_delimiter(pParam->bEnable) == false) { 1660 DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed"); 1661 return OMX_ErrorUnsupportedSetting; 1662 } 1663 1664 break; 1665 } 1666 case OMX_QcomIndexHierarchicalStructure: 1667 { 1668 QOMX_VIDEO_HIERARCHICALLAYERS* pParam = 1669 (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData; 1670 1671 if (pParam->nPortIndex == PORT_INDEX_OUT) { 1672 if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) { 1673 DEBUG_PRINT_ERROR("Setting Hier P count failed"); 1674 return false; 1675 } 1676 } else { 1677 DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex); 1678 return false; 1679 } 1680 1681 // For VP8, hier-p and ltr are mutually exclusive features in firmware 1682 // Disable ltr if hier-p is enabled. 1683 if (m_codec == OMX_VIDEO_CodingVP8) { 1684 DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set"); 1685 if(!venc_set_ltrmode(0, 1)) { 1686 DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode"); 1687 } 1688 } 1689 break; 1690 } 1691 case OMX_QcomIndexParamPerfLevel: 1692 { 1693 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam = 1694 (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData; 1695 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel); 1696 if(!venc_set_perf_level(pParam->ePerfLevel)) { 1697 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel); 1698 return false; 1699 } else { 1700 performance_level.perflevel = (unsigned int) pParam->ePerfLevel; 1701 } 1702 break; 1703 } 1704 case OMX_QcomIndexParamH264VUITimingInfo: 1705 { 1706 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam = 1707 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData; 1708 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable); 1709 if(venc_set_vui_timing_info(pParam->bEnable) == false) { 1710 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable); 1711 return false; 1712 } else { 1713 vui_timing_info.enabled = (unsigned int) pParam->bEnable; 1714 } 1715 break; 1716 } 1717 case OMX_QcomIndexParamPeakBitrate: 1718 { 1719 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam = 1720 (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData; 1721 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate); 1722 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) { 1723 DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate); 1724 return false; 1725 } else { 1726 peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate; 1727 } 1728 break; 1729 } 1730 case OMX_QcomIndexParamSetMVSearchrange: 1731 { 1732 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange"); 1733 is_searchrange_set = true; 1734 if (!venc_set_searchrange()) { 1735 DEBUG_PRINT_ERROR("ERROR: Failed to set search range"); 1736 return false; 1737 } 1738 } 1739 break; 1740 case OMX_IndexParamVideoSliceFMO: 1741 default: 1742 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u", 1743 index); 1744 break; 1745 //case 1746 } 1747 1748 return true; 1749 } 1750 1751 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) 1752 { 1753 1754 DEBUG_PRINT_LOW("Inside venc_set_config"); 1755 1756 switch ((int)index) { 1757 case OMX_IndexConfigVideoBitrate: 1758 { 1759 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) 1760 configData; 1761 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate"); 1762 1763 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1764 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) { 1765 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed"); 1766 return false; 1767 } 1768 } else { 1769 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); 1770 } 1771 1772 break; 1773 } 1774 case OMX_IndexConfigVideoFramerate: 1775 { 1776 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) 1777 configData; 1778 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate"); 1779 1780 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1781 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) { 1782 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed"); 1783 return false; 1784 } 1785 } else { 1786 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 1787 } 1788 1789 break; 1790 } 1791 case QOMX_IndexConfigVideoIntraperiod: 1792 { 1793 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod"); 1794 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = 1795 (QOMX_VIDEO_INTRAPERIODTYPE *)configData; 1796 1797 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1798 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) { 1799 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1800 return false; 1801 } 1802 } 1803 1804 break; 1805 } 1806 case OMX_IndexConfigVideoIntraVOPRefresh: 1807 { 1808 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) 1809 configData; 1810 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); 1811 1812 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1813 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) { 1814 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed"); 1815 return false; 1816 } 1817 } else { 1818 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 1819 } 1820 1821 break; 1822 } 1823 case OMX_IndexConfigCommonRotate: 1824 { 1825 OMX_CONFIG_ROTATIONTYPE *config_rotation = 1826 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 1827 OMX_U32 nFrameWidth; 1828 if (true == deinterlace_enabled) { 1829 DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing"); 1830 return false; 1831 } 1832 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims"); 1833 nFrameWidth = m_sVenc_cfg.dvs_width; 1834 m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height; 1835 m_sVenc_cfg.dvs_height = nFrameWidth; 1836 1837 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) { 1838 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed"); 1839 return false; 1840 } 1841 1842 break; 1843 } 1844 case OMX_IndexConfigVideoAVCIntraPeriod: 1845 { 1846 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; 1847 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod"); 1848 1849 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod) 1850 == false) { 1851 DEBUG_PRINT_ERROR("ERROR: Setting " 1852 "OMX_IndexConfigVideoAVCIntraPeriod failed"); 1853 return false; 1854 } 1855 break; 1856 } 1857 case OMX_IndexConfigCommonDeinterlace: 1858 { 1859 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData; 1860 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace"); 1861 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 1862 if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height && 1863 m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width) 1864 { 1865 DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation"); 1866 return false; 1867 } 1868 if(venc_set_deinterlace(deinterlace->nEnable) == false) { 1869 DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed"); 1870 return false; 1871 } 1872 } else { 1873 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace"); 1874 } 1875 break; 1876 } 1877 case OMX_IndexConfigVideoVp8ReferenceFrame: 1878 { 1879 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData; 1880 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame"); 1881 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) && 1882 (vp8refframe->bUseGoldenFrame)) { 1883 if(venc_set_useltr() == false) { 1884 DEBUG_PRINT_ERROR("ERROR: use goldenframe failed"); 1885 return false; 1886 } 1887 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) && 1888 (vp8refframe->bGoldenFrameRefresh)) { 1889 if(venc_set_markltr() == false) { 1890 DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed"); 1891 return false; 1892 } 1893 } else { 1894 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame"); 1895 } 1896 break; 1897 } 1898 default: 1899 DEBUG_PRINT_ERROR("Unsupported config index = %u", index); 1900 break; 1901 } 1902 1903 return true; 1904 } 1905 1906 unsigned venc_dev::venc_stop( void) 1907 { 1908 struct venc_msg venc_msg; 1909 struct v4l2_requestbuffers bufreq; 1910 int rc = 0, ret = 0; 1911 1912 if (!stopped) { 1913 enum v4l2_buf_type cap_type; 1914 1915 if (streaming[OUTPUT_PORT]) { 1916 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1917 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); 1918 1919 if (rc) { 1920 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d", 1921 cap_type, rc); 1922 } else 1923 streaming[OUTPUT_PORT] = false; 1924 1925 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port"); 1926 bufreq.memory = V4L2_MEMORY_USERPTR; 1927 bufreq.count = 0; 1928 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1929 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); 1930 1931 if (ret) { 1932 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed"); 1933 return false; 1934 } 1935 } 1936 1937 if (!rc && streaming[CAPTURE_PORT]) { 1938 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1939 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); 1940 1941 if (rc) { 1942 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d", 1943 cap_type, rc); 1944 } else 1945 streaming[CAPTURE_PORT] = false; 1946 1947 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port"); 1948 bufreq.memory = V4L2_MEMORY_USERPTR; 1949 bufreq.count = 0; 1950 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1951 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); 1952 1953 if (ret) { 1954 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed"); 1955 return false; 1956 } 1957 } 1958 1959 if (!rc && !ret) { 1960 venc_stop_done(); 1961 stopped = 1; 1962 /*set flag to re-configure when started again*/ 1963 resume_in_stopped = 1; 1964 1965 } 1966 } 1967 1968 return rc; 1969 } 1970 1971 unsigned venc_dev::venc_pause(void) 1972 { 1973 pthread_mutex_lock(&pause_resume_mlock); 1974 paused = true; 1975 pthread_mutex_unlock(&pause_resume_mlock); 1976 return 0; 1977 } 1978 1979 unsigned venc_dev::venc_resume(void) 1980 { 1981 pthread_mutex_lock(&pause_resume_mlock); 1982 paused = false; 1983 pthread_mutex_unlock(&pause_resume_mlock); 1984 1985 return pthread_cond_signal(&pause_resume_cond); 1986 } 1987 1988 unsigned venc_dev::venc_start_done(void) 1989 { 1990 struct venc_msg venc_msg; 1991 venc_msg.msgcode = VEN_MSG_START; 1992 venc_msg.statuscode = VEN_S_SUCCESS; 1993 venc_handle->async_message_process(venc_handle,&venc_msg); 1994 return 0; 1995 } 1996 1997 unsigned venc_dev::venc_stop_done(void) 1998 { 1999 struct venc_msg venc_msg; 2000 free_extradata(); 2001 venc_msg.msgcode=VEN_MSG_STOP; 2002 venc_msg.statuscode=VEN_S_SUCCESS; 2003 venc_handle->async_message_process(venc_handle,&venc_msg); 2004 return 0; 2005 } 2006 2007 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid) 2008 { 2009 async_thread_created = true; 2010 m_tid=tid; 2011 return 0; 2012 } 2013 2014 2015 unsigned venc_dev::venc_start(void) 2016 { 2017 enum v4l2_buf_type buf_type; 2018 int ret, r; 2019 struct v4l2_control control; 2020 2021 memset(&control, 0, sizeof(control)); 2022 2023 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start", 2024 __func__); 2025 2026 if (!venc_set_profile_level(0, 0)) { 2027 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET", 2028 __func__); 2029 } else { 2030 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET", 2031 __func__, codec_profile.profile, profile_level.level); 2032 } 2033 2034 venc_config_print(); 2035 2036 if(resume_in_stopped){ 2037 /*set buffercount when restarted*/ 2038 venc_reconfig_reqbufs(); 2039 resume_in_stopped = 0; 2040 } 2041 2042 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */ 2043 if (slice_mode.enable && multislice.mslice_size && 2044 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) { 2045 DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable, 2046 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size), 2047 MAX_SUPPORTED_SLICES_PER_FRAME); 2048 return 1; 2049 } 2050 2051 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2052 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2053 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type); 2054 2055 if (ret) 2056 return 1; 2057 2058 streaming[CAPTURE_PORT] = true; 2059 2060 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER; 2061 control.value = 1; 2062 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2063 if (ret) { 2064 DEBUG_PRINT_ERROR("failed to request seq header"); 2065 return 1; 2066 } 2067 2068 stopped = 0; 2069 return 0; 2070 } 2071 2072 void venc_dev::venc_config_print() 2073 { 2074 2075 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %ld, Profile %ld, level : %ld", 2076 m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); 2077 2078 DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld", 2079 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, 2080 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); 2081 2082 DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld", 2083 m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height, 2084 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); 2085 2086 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld", 2087 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); 2088 2089 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld", 2090 session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp); 2091 2092 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld", 2093 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp); 2094 2095 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld", 2096 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp); 2097 2098 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu", 2099 session_qp_values.minqp, session_qp_values.maxqp); 2100 2101 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld", 2102 voptimecfg.voptime_resolution, multislice.mslice_mode, 2103 multislice.mslice_size); 2104 2105 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld", 2106 entropy.longentropysel, entropy.cabacmodel); 2107 2108 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld", 2109 dbkfilter.db_mode, dbkfilter.slicealpha_offset, 2110 dbkfilter.slicebeta_offset); 2111 2112 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld", 2113 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod); 2114 2115 DEBUG_PRINT_HIGH("ENC_CONFIG: Hier-P layers: %d", hier_p_layers.numlayers); 2116 2117 DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel); 2118 2119 DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled); 2120 2121 DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate); 2122 } 2123 2124 bool venc_dev::venc_reconfig_reqbufs() 2125 { 2126 struct v4l2_requestbuffers bufreq; 2127 2128 bufreq.memory = V4L2_MEMORY_USERPTR; 2129 bufreq.count = m_sInput_buff_property.actualcount; 2130 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2131 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 2132 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume"); 2133 return false; 2134 } 2135 2136 bufreq.memory = V4L2_MEMORY_USERPTR; 2137 bufreq.count = m_sOutput_buff_property.actualcount; 2138 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2139 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) 2140 { 2141 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume"); 2142 return false; 2143 } 2144 return true; 2145 } 2146 2147 unsigned venc_dev::venc_flush( unsigned port) 2148 { 2149 struct v4l2_encoder_cmd enc; 2150 DEBUG_PRINT_LOW("in %s", __func__); 2151 2152 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH; 2153 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE; 2154 2155 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) { 2156 DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port); 2157 return -1; 2158 } 2159 2160 return 0; 2161 2162 } 2163 2164 //allocating I/P memory from pmem and register with the device 2165 2166 2167 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index) 2168 { 2169 2170 struct pmem *pmem_tmp; 2171 struct v4l2_buffer buf; 2172 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 2173 int rc = 0, extra_idx; 2174 2175 pmem_tmp = (struct pmem *)buf_addr; 2176 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp); 2177 2178 if (port == PORT_INDEX_IN) { 2179 buf.index = index; 2180 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2181 buf.memory = V4L2_MEMORY_USERPTR; 2182 plane[0].length = pmem_tmp->size; 2183 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; 2184 plane[0].reserved[0] = pmem_tmp->fd; 2185 plane[0].reserved[1] = 0; 2186 plane[0].data_offset = pmem_tmp->offset; 2187 buf.m.planes = plane; 2188 buf.length = 1; 2189 2190 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); 2191 2192 if (rc) 2193 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed"); 2194 } else if (port == PORT_INDEX_OUT) { 2195 extra_idx = EXTRADATA_IDX(num_planes); 2196 2197 if ((num_planes > 1) && (extra_idx)) { 2198 rc = allocate_extradata(); 2199 2200 if (rc) 2201 DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", rc); 2202 } 2203 2204 buf.index = index; 2205 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2206 buf.memory = V4L2_MEMORY_USERPTR; 2207 plane[0].length = pmem_tmp->size; 2208 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; 2209 plane[0].reserved[0] = pmem_tmp->fd; 2210 plane[0].reserved[1] = 0; 2211 plane[0].data_offset = pmem_tmp->offset; 2212 buf.m.planes = plane; 2213 buf.length = num_planes; 2214 2215 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 2216 plane[extra_idx].length = extradata_info.buffer_size; 2217 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); 2218 #ifdef USE_ION 2219 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; 2220 #endif 2221 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; 2222 plane[extra_idx].data_offset = 0; 2223 } else if (extra_idx >= VIDEO_MAX_PLANES) { 2224 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 2225 return OMX_ErrorBadParameter; 2226 } 2227 2228 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); 2229 2230 if (rc) 2231 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed"); 2232 } else { 2233 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index "); 2234 return false; 2235 } 2236 2237 return true; 2238 } 2239 2240 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) 2241 { 2242 struct pmem *pmem_tmp; 2243 struct venc_bufferpayload dev_buffer; 2244 2245 memset(&dev_buffer, 0, sizeof(dev_buffer)); 2246 pmem_tmp = (struct pmem *)buf_addr; 2247 2248 if (port == PORT_INDEX_IN) { 2249 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 2250 dev_buffer.fd = pmem_tmp->fd; 2251 dev_buffer.maped_size = pmem_tmp->size; 2252 dev_buffer.sz = pmem_tmp->size; 2253 dev_buffer.offset = pmem_tmp->offset; 2254 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \ 2255 dev_buffer.pbuffer, \ 2256 dev_buffer.fd, \ 2257 dev_buffer.offset, \ 2258 dev_buffer.maped_size); 2259 2260 } else if (port == PORT_INDEX_OUT) { 2261 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 2262 dev_buffer.fd = pmem_tmp->fd; 2263 dev_buffer.sz = pmem_tmp->size; 2264 dev_buffer.maped_size = pmem_tmp->size; 2265 dev_buffer.offset = pmem_tmp->offset; 2266 2267 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \ 2268 dev_buffer.pbuffer, \ 2269 dev_buffer.fd, \ 2270 dev_buffer.offset, \ 2271 dev_buffer.maped_size); 2272 } else { 2273 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index "); 2274 return false; 2275 } 2276 2277 return true; 2278 } 2279 2280 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer, 2281 OMX_U32 width, OMX_U32 height) 2282 { 2283 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width), 2284 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height), 2285 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width), 2286 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height), 2287 src_chroma_offset = width * height; 2288 2289 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) { 2290 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer; 2291 //Do chroma first, so that we can convert it in-place 2292 src_buf += width * height; 2293 dst_buf += y_stride * y_scanlines; 2294 for (int line = height / 2 - 1; line >= 0; --line) { 2295 memmove(dst_buf + line * uv_stride, 2296 src_buf + line * width, 2297 width); 2298 } 2299 2300 dst_buf = src_buf = buffer->pBuffer; 2301 //Copy the Y next 2302 for (int line = height - 1; line > 0; --line) { 2303 memmove(dst_buf + line * y_stride, 2304 src_buf + line * width, 2305 width); 2306 } 2307 } else { 2308 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \ 2309 Insufficient bufferLen=%u v/s Required=%u", 2310 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen, 2311 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)); 2312 return false; 2313 } 2314 2315 return true; 2316 } 2317 2318 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel) 2319 { 2320 if (!perflevel) { 2321 DEBUG_PRINT_ERROR("Null pointer error"); 2322 return false; 2323 } else { 2324 *perflevel = performance_level.perflevel; 2325 return true; 2326 } 2327 } 2328 2329 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled) 2330 { 2331 if (!enabled) { 2332 DEBUG_PRINT_ERROR("Null pointer error"); 2333 return false; 2334 } else { 2335 *enabled = vui_timing_info.enabled; 2336 return true; 2337 } 2338 } 2339 2340 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate) 2341 { 2342 if (!peakbitrate) { 2343 DEBUG_PRINT_ERROR("Null pointer error"); 2344 return false; 2345 } else { 2346 *peakbitrate = peak_bitrate.peakbitrate; 2347 return true; 2348 } 2349 } 2350 2351 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd) 2352 { 2353 struct pmem *temp_buffer; 2354 struct v4l2_buffer buf; 2355 struct v4l2_plane plane; 2356 int rc=0; 2357 struct OMX_BUFFERHEADERTYPE *bufhdr; 2358 encoder_media_buffer_type * meta_buf = NULL; 2359 temp_buffer = (struct pmem *)buffer; 2360 2361 memset (&buf, 0, sizeof(buf)); 2362 memset (&plane, 0, sizeof(plane)); 2363 2364 if (buffer == NULL) { 2365 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL"); 2366 return false; 2367 } 2368 2369 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 2370 2371 DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen); 2372 2373 if (pmem_data_buf) { 2374 DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 2375 plane.m.userptr = (unsigned long)pmem_data_buf; 2376 plane.data_offset = bufhdr->nOffset; 2377 plane.length = bufhdr->nAllocLen; 2378 plane.bytesused = bufhdr->nFilledLen; 2379 } else { 2380 // -------------------------------------------------------------------------------------- 2381 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info] 2382 // --------------------------------------------------------------------------------------- 2383 // Camera-2 1 CameraSource 0 meta-handle 2384 // Camera-3 1 GrallocSource 0 gralloc-private-handle 2385 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted) 2386 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr 2387 // --------------------------------------------------------------------------------------- 2388 if (metadatamode) { 2389 plane.m.userptr = index; 2390 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer; 2391 2392 if (!meta_buf) { 2393 //empty EOS buffer 2394 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) { 2395 plane.data_offset = bufhdr->nOffset; 2396 plane.length = bufhdr->nAllocLen; 2397 plane.bytesused = bufhdr->nFilledLen; 2398 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer"); 2399 } else { 2400 return false; 2401 } 2402 } else if (!color_format) { 2403 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) { 2404 if (meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709) 2405 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP; 2406 plane.data_offset = meta_buf->meta_handle->data[1]; 2407 plane.length = meta_buf->meta_handle->data[2]; 2408 plane.bytesused = meta_buf->meta_handle->data[2]; 2409 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x", 2410 fd, plane.bytesused, plane.length, buf.flags); 2411 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) { 2412 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle; 2413 fd = handle->fd; 2414 plane.data_offset = 0; 2415 plane.length = handle->size; 2416 plane.bytesused = handle->size; 2417 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d " 2418 ": filled %d of %d", fd, plane.bytesused, plane.length); 2419 } 2420 } else { 2421 plane.data_offset = bufhdr->nOffset; 2422 plane.length = bufhdr->nAllocLen; 2423 plane.bytesused = bufhdr->nFilledLen; 2424 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d " 2425 ": filled %d of %d", fd, plane.bytesused, plane.length); 2426 } 2427 } else { 2428 plane.data_offset = bufhdr->nOffset; 2429 plane.length = bufhdr->nAllocLen; 2430 plane.bytesused = bufhdr->nFilledLen; 2431 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d", 2432 fd, plane.bytesused, plane.length); 2433 } 2434 } 2435 2436 buf.index = index; 2437 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2438 buf.memory = V4L2_MEMORY_USERPTR; 2439 plane.reserved[0] = fd; 2440 plane.reserved[1] = 0; 2441 buf.m.planes = &plane; 2442 buf.length = 1; 2443 2444 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) 2445 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS; 2446 2447 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000; 2448 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000); 2449 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 2450 2451 if (rc) { 2452 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver"); 2453 return false; 2454 } 2455 2456 etb++; 2457 2458 if (!streaming[OUTPUT_PORT]) { 2459 enum v4l2_buf_type buf_type; 2460 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2461 int ret; 2462 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type); 2463 2464 if (ret) { 2465 DEBUG_PRINT_ERROR("Failed to call streamon"); 2466 return false; 2467 } else { 2468 streaming[OUTPUT_PORT] = true; 2469 } 2470 } 2471 if (m_debug.in_buffer_log) { 2472 venc_input_log_buffers(bufhdr, fd, plane.data_offset); 2473 } 2474 2475 return true; 2476 } 2477 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) 2478 { 2479 struct pmem *temp_buffer = NULL; 2480 struct venc_buffer frameinfo; 2481 struct v4l2_buffer buf; 2482 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 2483 int rc = 0, extra_idx; 2484 struct OMX_BUFFERHEADERTYPE *bufhdr; 2485 2486 if (buffer == NULL) 2487 return false; 2488 2489 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 2490 2491 if (pmem_data_buf) { 2492 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); 2493 plane[0].m.userptr = (unsigned long)pmem_data_buf; 2494 } else { 2495 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 2496 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer; 2497 } 2498 2499 buf.index = index; 2500 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2501 buf.memory = V4L2_MEMORY_USERPTR; 2502 plane[0].length = bufhdr->nAllocLen; 2503 plane[0].bytesused = bufhdr->nFilledLen; 2504 plane[0].reserved[0] = fd; 2505 plane[0].reserved[1] = 0; 2506 plane[0].data_offset = bufhdr->nOffset; 2507 buf.m.planes = plane; 2508 buf.length = num_planes; 2509 2510 extra_idx = EXTRADATA_IDX(num_planes); 2511 2512 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 2513 plane[extra_idx].bytesused = 0; 2514 plane[extra_idx].length = extradata_info.buffer_size; 2515 plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); 2516 #ifdef USE_ION 2517 plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; 2518 #endif 2519 plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; 2520 plane[extra_idx].data_offset = 0; 2521 } else if (extra_idx >= VIDEO_MAX_PLANES) { 2522 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx); 2523 return false; 2524 } 2525 2526 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 2527 2528 if (rc) { 2529 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver"); 2530 return false; 2531 } 2532 2533 ftb++; 2534 return true; 2535 } 2536 2537 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable) 2538 { 2539 struct v4l2_control control; 2540 2541 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; 2542 if(enable) { 2543 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME; 2544 } else { 2545 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; 2546 } 2547 2548 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable); 2549 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) { 2550 DEBUG_PRINT_ERROR("Request for inband sps/pps failed"); 2551 return false; 2552 } 2553 return true; 2554 } 2555 2556 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable) 2557 { 2558 struct v4l2_control control; 2559 2560 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER; 2561 if(enable) { 2562 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED; 2563 } else { 2564 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED; 2565 } 2566 2567 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable); 2568 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) { 2569 DEBUG_PRINT_ERROR("Request to set AU delimiter failed"); 2570 return false; 2571 } 2572 return true; 2573 } 2574 2575 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type, 2576 OMX_U32 num_layers) 2577 { 2578 struct v4l2_control control; 2579 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS; 2580 if (type == QOMX_HIERARCHICALCODING_P) { 2581 control.value = num_layers; 2582 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers); 2583 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 2584 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed"); 2585 return false; 2586 } 2587 hier_p_layers.numlayers = num_layers; 2588 } else { 2589 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type); 2590 return false; 2591 } 2592 return true; 2593 } 2594 2595 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable) 2596 { 2597 struct v4l2_control control; 2598 2599 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data); 2600 2601 if (enable == OMX_FALSE) { 2602 /* No easy way to turn off extradata to the driver 2603 * at the moment */ 2604 return false; 2605 } 2606 2607 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 2608 switch (extra_data) { 2609 case OMX_ExtraDataVideoEncoderSliceInfo: 2610 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO; 2611 break; 2612 case OMX_ExtraDataVideoEncoderMBInfo: 2613 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI; 2614 break; 2615 default: 2616 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data); 2617 return false; 2618 } 2619 2620 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 2621 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d", 2622 (unsigned int)extra_data, errno); 2623 return false; 2624 } 2625 2626 return true; 2627 } 2628 2629 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable) 2630 { 2631 struct v4l2_control control; 2632 2633 if (enable) { 2634 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE; 2635 control.value = 1; 2636 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value); 2637 2638 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2639 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 2640 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); 2641 return false; 2642 } else { 2643 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value); 2644 slice_mode.enable = 1; 2645 } 2646 } else { 2647 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] " 2648 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode, 2649 m_sVenc_cfg.codectype); 2650 } 2651 } else { 2652 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled"); 2653 } 2654 2655 return true; 2656 } 2657 2658 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp) 2659 { 2660 int rc; 2661 struct v4l2_control control; 2662 struct v4l2_ext_control ctrl[4]; 2663 struct v4l2_ext_controls controls; 2664 2665 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP; 2666 ctrl[0].value = initqp->nQpI; 2667 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP; 2668 ctrl[1].value = initqp->nQpP; 2669 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP; 2670 ctrl[2].value = initqp->nQpB; 2671 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP; 2672 ctrl[3].value = initqp->bEnableInitQp; 2673 2674 controls.count = 4; 2675 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 2676 controls.controls = ctrl; 2677 2678 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d", 2679 controls.controls[0].id, controls.controls[0].value, 2680 controls.controls[1].id, controls.controls[1].value, 2681 controls.controls[2].id, controls.controls[2].value, 2682 controls.controls[3].id, controls.controls[3].value); 2683 2684 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 2685 if (rc) { 2686 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc); 2687 return false; 2688 } 2689 2690 init_qp.iframeqp = initqp->nQpI; 2691 init_qp.pframeqp = initqp->nQpP; 2692 init_qp.bframeqp = initqp->nQpB; 2693 init_qp.enableinitqp = initqp->bEnableInitQp; 2694 2695 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d", 2696 controls.controls[0].id, controls.controls[0].value, 2697 controls.controls[1].id, controls.controls[1].value, 2698 controls.controls[2].id, controls.controls[2].value, 2699 controls.controls[3].id, controls.controls[3].value); 2700 return true; 2701 } 2702 2703 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp) 2704 { 2705 int rc; 2706 struct v4l2_control control; 2707 2708 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; 2709 control.value = i_frame_qp; 2710 2711 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 2712 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2713 2714 if (rc) { 2715 DEBUG_PRINT_ERROR("Failed to set control"); 2716 return false; 2717 } 2718 2719 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 2720 session_qp.iframeqp = control.value; 2721 2722 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; 2723 control.value = p_frame_qp; 2724 2725 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 2726 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2727 2728 if (rc) { 2729 DEBUG_PRINT_ERROR("Failed to set control"); 2730 return false; 2731 } 2732 2733 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 2734 2735 session_qp.pframeqp = control.value; 2736 2737 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) || 2738 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { 2739 2740 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; 2741 control.value = b_frame_qp; 2742 2743 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 2744 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2745 2746 if (rc) { 2747 DEBUG_PRINT_ERROR("Failed to set control"); 2748 return false; 2749 } 2750 2751 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 2752 2753 session_qp.bframeqp = control.value; 2754 } 2755 2756 return true; 2757 } 2758 2759 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp) 2760 { 2761 int rc; 2762 struct v4l2_control control; 2763 2764 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) { 2765 2766 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) 2767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP; 2768 else 2769 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP; 2770 control.value = min_qp; 2771 2772 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d", 2773 control.id, control.value); 2774 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2775 if (rc) { 2776 DEBUG_PRINT_ERROR("Failed to set control\n"); 2777 return false; 2778 } 2779 2780 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) 2781 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP; 2782 else 2783 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP; 2784 control.value = max_qp; 2785 2786 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d", 2787 control.id, control.value); 2788 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2789 if (rc) { 2790 DEBUG_PRINT_ERROR("Failed to set control\n"); 2791 return false; 2792 } 2793 } else { 2794 DEBUG_PRINT_ERROR("Wrong qp values[%lu %lu], allowed range[%lu %lu]", 2795 min_qp, max_qp, session_qp_range.minqp, session_qp_range.maxqp); 2796 } 2797 2798 return true; 2799 } 2800 2801 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) 2802 { 2803 struct venc_profile requested_profile = {0}; 2804 struct ven_profilelevel requested_level = {0}; 2805 unsigned long mb_per_frame = 0; 2806 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u", 2807 (unsigned int)eProfile, (unsigned int)eLevel); 2808 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)* 2809 ((m_sVenc_cfg.dvs_width + 15) >> 4); 2810 2811 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) { 2812 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start"); 2813 return true; 2814 } 2815 2816 DEBUG_PRINT_LOW("Validating Profile/Level from table"); 2817 2818 if (!venc_validate_profile_level(&eProfile, &eLevel)) { 2819 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed"); 2820 return false; 2821 } 2822 2823 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 2824 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and " 2825 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile, 2826 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); 2827 2828 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 2829 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; 2830 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 2831 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE; 2832 } else { 2833 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u", 2834 (unsigned int)eProfile); 2835 return false; 2836 } 2837 2838 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," 2839 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," 2840 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, 2841 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); 2842 2843 if (mb_per_frame >= 3600) { 2844 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) 2845 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 2846 2847 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) 2848 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 2849 } else { 2850 switch (eLevel) { 2851 case OMX_VIDEO_MPEG4Level0: 2852 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0; 2853 break; 2854 case OMX_VIDEO_MPEG4Level0b: 2855 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B; 2856 break; 2857 case OMX_VIDEO_MPEG4Level1: 2858 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1; 2859 break; 2860 case OMX_VIDEO_MPEG4Level2: 2861 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; 2862 break; 2863 case OMX_VIDEO_MPEG4Level3: 2864 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3; 2865 break; 2866 case OMX_VIDEO_MPEG4Level4a: 2867 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4; 2868 break; 2869 case OMX_VIDEO_MPEG4Level5: 2870 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 2871 break; 2872 default: 2873 return false; 2874 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 2875 break; 2876 } 2877 } 2878 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 2879 2880 switch (eProfile) { 2881 case OMX_VIDEO_H263ProfileBaseline: 2882 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE; 2883 break; 2884 case OMX_VIDEO_H263ProfileH320Coding: 2885 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING; 2886 break; 2887 case OMX_VIDEO_H263ProfileBackwardCompatible: 2888 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE; 2889 break; 2890 case OMX_VIDEO_H263ProfileISWV2: 2891 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2; 2892 break; 2893 case OMX_VIDEO_H263ProfileISWV3: 2894 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3; 2895 break; 2896 case OMX_VIDEO_H263ProfileHighCompression: 2897 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION; 2898 break; 2899 case OMX_VIDEO_H263ProfileInternet: 2900 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET; 2901 break; 2902 case OMX_VIDEO_H263ProfileInterlace: 2903 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE; 2904 break; 2905 case OMX_VIDEO_H263ProfileHighLatency: 2906 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY; 2907 break; 2908 default: 2909 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu", 2910 requested_profile.profile); 2911 return false; 2912 } 2913 2914 //profile level 2915 switch (eLevel) { 2916 case OMX_VIDEO_H263Level10: 2917 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0; 2918 break; 2919 case OMX_VIDEO_H263Level20: 2920 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0; 2921 break; 2922 case OMX_VIDEO_H263Level30: 2923 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0; 2924 break; 2925 case OMX_VIDEO_H263Level40: 2926 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0; 2927 break; 2928 case OMX_VIDEO_H263Level45: 2929 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5; 2930 break; 2931 case OMX_VIDEO_H263Level50: 2932 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0; 2933 break; 2934 case OMX_VIDEO_H263Level60: 2935 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0; 2936 break; 2937 case OMX_VIDEO_H263Level70: 2938 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0; 2939 break; 2940 default: 2941 return false; 2942 break; 2943 } 2944 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 2945 if (eProfile == OMX_VIDEO_AVCProfileBaseline) { 2946 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; 2947 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) { 2948 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE; 2949 } else if (eProfile == OMX_VIDEO_AVCProfileMain) { 2950 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN; 2951 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) { 2952 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED; 2953 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) { 2954 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; 2955 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) { 2956 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10; 2957 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) { 2958 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422; 2959 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) { 2960 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE; 2961 } else { 2962 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu", 2963 requested_profile.profile); 2964 return false; 2965 } 2966 2967 //profile level 2968 switch (eLevel) { 2969 case OMX_VIDEO_AVCLevel1: 2970 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; 2971 break; 2972 case OMX_VIDEO_AVCLevel1b: 2973 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B; 2974 break; 2975 case OMX_VIDEO_AVCLevel11: 2976 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1; 2977 break; 2978 case OMX_VIDEO_AVCLevel12: 2979 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2; 2980 break; 2981 case OMX_VIDEO_AVCLevel13: 2982 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3; 2983 break; 2984 case OMX_VIDEO_AVCLevel2: 2985 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0; 2986 break; 2987 case OMX_VIDEO_AVCLevel21: 2988 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1; 2989 break; 2990 case OMX_VIDEO_AVCLevel22: 2991 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2; 2992 break; 2993 case OMX_VIDEO_AVCLevel3: 2994 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0; 2995 break; 2996 case OMX_VIDEO_AVCLevel31: 2997 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1; 2998 break; 2999 case OMX_VIDEO_AVCLevel32: 3000 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2; 3001 break; 3002 case OMX_VIDEO_AVCLevel4: 3003 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; 3004 break; 3005 case OMX_VIDEO_AVCLevel41: 3006 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; 3007 break; 3008 case OMX_VIDEO_AVCLevel42: 3009 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2; 3010 break; 3011 case OMX_VIDEO_AVCLevel5: 3012 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0; 3013 break; 3014 case OMX_VIDEO_AVCLevel51: 3015 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1; 3016 break; 3017 case OMX_VIDEO_AVCLevel52: 3018 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2; 3019 break; 3020 case OMX_VIDEO_AVCLevelMax: 3021 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2; 3022 break; 3023 default : 3024 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu", 3025 requested_level.level); 3026 return false; 3027 break; 3028 } 3029 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 3030 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) { 3031 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u", 3032 (unsigned int)eProfile); 3033 return false; 3034 } 3035 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; 3036 m_profile_set = true; 3037 switch(eLevel) { 3038 case OMX_VIDEO_VP8Level_Version0: 3039 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; 3040 break; 3041 case OMX_VIDEO_VP8Level_Version1: 3042 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1; 3043 break; 3044 default: 3045 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u", 3046 (unsigned int)eLevel); 3047 return false; 3048 break; 3049 } 3050 } 3051 3052 if (!m_profile_set) { 3053 int rc; 3054 struct v4l2_control control; 3055 3056 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 3057 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; 3058 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 3059 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE; 3060 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 3061 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE; 3062 } else { 3063 DEBUG_PRINT_ERROR("Wrong CODEC"); 3064 return false; 3065 } 3066 3067 control.value = requested_profile.profile; 3068 3069 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3070 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3071 3072 if (rc) { 3073 DEBUG_PRINT_ERROR("Failed to set control"); 3074 return false; 3075 } 3076 3077 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3078 3079 codec_profile.profile = control.value; 3080 m_profile_set = true; 3081 } 3082 3083 if (!m_level_set) { 3084 int rc; 3085 struct v4l2_control control; 3086 3087 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 3088 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; 3089 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 3090 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL; 3091 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 3092 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL; 3093 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 3094 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL; 3095 } else { 3096 DEBUG_PRINT_ERROR("Wrong CODEC"); 3097 return false; 3098 } 3099 3100 control.value = requested_level.level; 3101 3102 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3103 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3104 3105 if (rc) { 3106 DEBUG_PRINT_ERROR("Failed to set control"); 3107 return false; 3108 } 3109 3110 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3111 3112 profile_level.level = control.value; 3113 m_level_set = true; 3114 } 3115 3116 return true; 3117 } 3118 3119 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) 3120 { 3121 3122 struct venc_voptimingcfg vop_timing_cfg; 3123 3124 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u", 3125 (unsigned int)TimeIncRes); 3126 3127 vop_timing_cfg.voptime_resolution = TimeIncRes; 3128 3129 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; 3130 return true; 3131 } 3132 3133 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) 3134 { 3135 3136 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames); 3137 int rc; 3138 struct v4l2_control control; 3139 int pframe = 0, bframe = 0; 3140 3141 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) && 3142 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && 3143 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { 3144 nBFrames=0; 3145 } 3146 if ((display_info.w * display_info.h > OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT) 3147 && enable_mv_narrow_searchrange && (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >= 3148 OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT || is_searchrange_set)) { 3149 nBFrames=0; 3150 } 3151 3152 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 3153 control.value = nPFrames; 3154 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3155 3156 if (rc) { 3157 DEBUG_PRINT_ERROR("Failed to set control"); 3158 return false; 3159 } 3160 3161 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3162 3163 intra_period.num_pframes = control.value; 3164 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; 3165 control.value = nBFrames; 3166 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3167 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3168 3169 if (rc) { 3170 DEBUG_PRINT_ERROR("Failed to set control"); 3171 return false; 3172 } 3173 3174 intra_period.num_bframes = nBFrames; 3175 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes); 3176 3177 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 3178 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 3179 control.value = 1; 3180 3181 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3182 3183 if (rc) { 3184 DEBUG_PRINT_ERROR("Failed to set control"); 3185 return false; 3186 } 3187 3188 idrperiod.idrperiod = 1; 3189 } 3190 3191 return true; 3192 } 3193 3194 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod) 3195 { 3196 int rc = 0; 3197 struct v4l2_control control; 3198 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u", 3199 (unsigned int)nPFrames, (unsigned int)nIDRPeriod); 3200 3201 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) { 3202 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!"); 3203 return false; 3204 } 3205 3206 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) { 3207 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 3208 return false; 3209 } 3210 3211 if (!intra_period.num_bframes) 3212 intra_period.num_pframes = nPFrames; 3213 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 3214 control.value = nIDRPeriod; 3215 3216 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3217 3218 if (rc) { 3219 DEBUG_PRINT_ERROR("Failed to set control"); 3220 return false; 3221 } 3222 3223 idrperiod.idrperiod = nIDRPeriod; 3224 return true; 3225 } 3226 3227 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) 3228 { 3229 int rc = 0; 3230 struct v4l2_control control; 3231 3232 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level); 3233 3234 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) && 3235 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) { 3236 3237 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC; 3238 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 3239 3240 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3241 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3242 3243 if (rc) { 3244 DEBUG_PRINT_ERROR("Failed to set control"); 3245 return false; 3246 } 3247 3248 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3249 entropy.longentropysel = control.value; 3250 3251 if (i_cabac_level == 0) { 3252 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0; 3253 } else if (i_cabac_level == 1) { 3254 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1; 3255 } else if (i_cabac_level == 2) { 3256 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2; 3257 } 3258 3259 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL; 3260 //control.value = entropy_cfg.cabacmodel; 3261 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3262 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3263 3264 if (rc) { 3265 DEBUG_PRINT_ERROR("Failed to set control"); 3266 return false; 3267 } 3268 3269 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3270 entropy.cabacmodel=control.value; 3271 } else if (!enable) { 3272 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; 3273 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 3274 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3275 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3276 3277 if (rc) { 3278 DEBUG_PRINT_ERROR("Failed to set control"); 3279 return false; 3280 } 3281 3282 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3283 entropy.longentropysel=control.value; 3284 } else { 3285 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile"); 3286 return false; 3287 } 3288 3289 return true; 3290 } 3291 3292 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB 3293 { 3294 int rc; 3295 struct v4l2_control control; 3296 bool status = true; 3297 3298 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) { 3299 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB; 3300 } else { 3301 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; 3302 } 3303 3304 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 3305 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3306 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3307 3308 if (rc) { 3309 DEBUG_PRINT_ERROR("Failed to set control"); 3310 return false; 3311 } 3312 3313 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3314 multislice.mslice_mode=control.value; 3315 3316 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) { 3317 3318 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; 3319 control.value = nSlicesize; 3320 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value); 3321 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3322 3323 if (rc) { 3324 DEBUG_PRINT_ERROR("Failed to set control"); 3325 return false; 3326 } 3327 3328 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3329 multislice.mslice_size=control.value; 3330 3331 } 3332 3333 return status; 3334 } 3335 3336 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) 3337 { 3338 bool status = true; 3339 int rc; 3340 struct v4l2_control control_mode,control_mbs; 3341 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE; 3342 3343 // There is no disabled mode. Disabled mode is indicated by a 0 count. 3344 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) { 3345 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE; 3346 return status; 3347 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && 3348 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 3349 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC; 3350 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS; 3351 control_mbs.value=irMBs; 3352 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) && 3353 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 3354 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE; 3355 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS; 3356 control_mbs.value=irMBs; 3357 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) && 3358 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 3359 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE; 3360 } else { 3361 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:" 3362 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode); 3363 return false; 3364 } 3365 3366 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value); 3367 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode); 3368 3369 if (rc) { 3370 DEBUG_PRINT_ERROR("Failed to set control"); 3371 return false; 3372 } 3373 3374 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value); 3375 3376 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value); 3377 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs); 3378 3379 if (rc) { 3380 DEBUG_PRINT_ERROR("Failed to set control"); 3381 return false; 3382 } 3383 3384 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value); 3385 3386 intra_refresh.irmode = control_mode.value; 3387 intra_refresh.mbcount = control_mbs.value; 3388 3389 return status; 3390 } 3391 3392 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) 3393 { 3394 bool status = true; 3395 struct venc_headerextension hec_cfg; 3396 struct venc_multiclicecfg multislice_cfg; 3397 int rc; 3398 OMX_U32 resynchMarkerSpacingBytes = 0; 3399 struct v4l2_control control; 3400 3401 memset(&control, 0, sizeof(control)); 3402 3403 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 3404 if (error_resilience->bEnableHEC) { 3405 hec_cfg.header_extension = 1; 3406 } else { 3407 hec_cfg.header_extension = 0; 3408 } 3409 3410 hec.header_extension = error_resilience->bEnableHEC; 3411 } 3412 3413 if (error_resilience->bEnableRVLC) { 3414 DEBUG_PRINT_ERROR("RVLC is not Supported"); 3415 return false; 3416 } 3417 3418 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && 3419 (error_resilience->bEnableDataPartitioning)) { 3420 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264"); 3421 return false; 3422 } 3423 3424 if (error_resilience->nResynchMarkerSpacing) { 3425 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing; 3426 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3; 3427 } 3428 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && 3429 (error_resilience->nResynchMarkerSpacing)) { 3430 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; 3431 multislice_cfg.mslice_size = resynchMarkerSpacingBytes; 3432 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 3433 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES; 3434 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 && 3435 error_resilience->bEnableDataPartitioning) { 3436 multislice_cfg.mslice_mode = VEN_MSLICE_GOB; 3437 multislice_cfg.mslice_size = resynchMarkerSpacingBytes; 3438 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 3439 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB; 3440 } else { 3441 multislice_cfg.mslice_mode = VEN_MSLICE_OFF; 3442 multislice_cfg.mslice_size = 0; 3443 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 3444 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; 3445 } 3446 3447 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__, 3448 multislice_cfg.mslice_mode, multislice_cfg.mslice_size); 3449 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 3450 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3451 3452 if (rc) { 3453 DEBUG_PRINT_ERROR("Failed to set Slice mode control"); 3454 return false; 3455 } 3456 3457 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 3458 multislice.mslice_mode=control.value; 3459 3460 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; 3461 control.value = resynchMarkerSpacingBytes; 3462 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 3463 3464 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3465 3466 if (rc) { 3467 DEBUG_PRINT_ERROR("Failed to set MAX MB control"); 3468 return false; 3469 } 3470 3471 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 3472 multislice.mslice_mode = multislice_cfg.mslice_mode; 3473 multislice.mslice_size = multislice_cfg.mslice_size; 3474 return status; 3475 } 3476 3477 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) 3478 { 3479 int rc; 3480 struct v4l2_control control; 3481 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE; 3482 3483 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) { 3484 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED; 3485 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) { 3486 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED; 3487 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) { 3488 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY; 3489 } 3490 3491 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3492 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3493 3494 if (rc) { 3495 return false; 3496 } 3497 3498 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3499 3500 dbkfilter.db_mode=control.value; 3501 3502 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA; 3503 control.value=0; 3504 3505 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3506 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3507 3508 if (rc) { 3509 return false; 3510 } 3511 3512 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3513 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA; 3514 control.value=0; 3515 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3516 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3517 3518 if (rc) { 3519 return false; 3520 } 3521 3522 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3523 3524 3525 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; 3526 return true; 3527 } 3528 3529 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) 3530 { 3531 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u", 3532 (unsigned int)nTargetBitrate); 3533 struct v4l2_control control; 3534 int rc = 0; 3535 control.id = V4L2_CID_MPEG_VIDEO_BITRATE; 3536 control.value = nTargetBitrate; 3537 3538 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3539 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3540 3541 if (rc) { 3542 DEBUG_PRINT_ERROR("Failed to set control"); 3543 return false; 3544 } 3545 3546 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3547 3548 3549 m_sVenc_cfg.targetbitrate = control.value; 3550 bitrate.target_bitrate = control.value; 3551 3552 if (!config) { 3553 m_level_set = false; 3554 3555 if (venc_set_profile_level(0, 0)) { 3556 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level); 3557 } 3558 } 3559 3560 return true; 3561 } 3562 3563 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) 3564 { 3565 struct v4l2_streamparm parm; 3566 int rc = 0; 3567 struct venc_framerate frame_rate_cfg; 3568 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); 3569 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3570 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator; 3571 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator; 3572 3573 if (frame_rate_cfg.fps_numerator > 0) 3574 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm); 3575 3576 if (rc) { 3577 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed"); 3578 return false; 3579 } 3580 3581 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; 3582 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; 3583 3584 if (!config) { 3585 m_level_set = false; 3586 3587 if (venc_set_profile_level(0, 0)) { 3588 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level); 3589 } 3590 } 3591 3592 return true; 3593 } 3594 3595 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) 3596 { 3597 struct v4l2_format fmt; 3598 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format); 3599 3600 if ((int)color_format == (int)OMX_COLOR_FormatYUV420SemiPlanar || 3601 (int)color_format == (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { 3602 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 3603 } else if ((int)color_format == (int)QOMX_COLOR_FormatYVU420SemiPlanar) { 3604 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21; 3605 } else { 3606 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format); 3607 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 3608 DEBUG_PRINT_HIGH("Default color format YUV420SemiPlanar is set"); 3609 } 3610 3611 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3612 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 3613 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 3614 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 3615 3616 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 3617 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format); 3618 return false; 3619 } 3620 3621 return true; 3622 } 3623 3624 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) 3625 { 3626 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); 3627 3628 if (intra_vop_refresh == OMX_TRUE) { 3629 struct v4l2_control control; 3630 int rc; 3631 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME; 3632 control.value = 1; 3633 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 3634 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3635 3636 if (rc) { 3637 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control"); 3638 return false; 3639 } 3640 3641 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 3642 } else { 3643 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect"); 3644 } 3645 3646 return true; 3647 } 3648 3649 bool venc_dev::venc_set_deinterlace(OMX_U32 enable) 3650 { 3651 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable); 3652 struct v4l2_control control; 3653 int rc; 3654 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE; 3655 if (enable) 3656 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED; 3657 else 3658 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED; 3659 3660 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 3661 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3662 if (rc) { 3663 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control"); 3664 return false; 3665 } 3666 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 3667 deinterlace_enabled = true; 3668 return true; 3669 } 3670 3671 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count) 3672 { 3673 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable); 3674 struct v4l2_control control; 3675 struct v4l2_ext_control ctrl[2]; 3676 struct v4l2_ext_controls controls; 3677 int rc; 3678 3679 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE; 3680 if (enable) 3681 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL; 3682 else 3683 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE; 3684 3685 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT; 3686 if (count) 3687 ctrl[1].value = count; 3688 else 3689 ctrl[1].value = 1; 3690 3691 controls.count = 2; 3692 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 3693 controls.controls = ctrl; 3694 3695 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d", 3696 controls.controls[0].id, controls.controls[0].value, 3697 controls.controls[1].id, controls.controls[1].value); 3698 3699 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 3700 if (rc) { 3701 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc); 3702 return false; 3703 } 3704 3705 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d", 3706 controls.controls[0].id, controls.controls[0].value, 3707 controls.controls[1].id, controls.controls[1].value); 3708 3709 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 3710 control.value = V4L2_MPEG_VIDC_EXTRADATA_LTR; 3711 3712 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 3713 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); 3714 return false; 3715 } 3716 return true; 3717 } 3718 3719 bool venc_dev::venc_set_useltr() 3720 { 3721 DEBUG_PRINT_LOW("venc_use_goldenframe"); 3722 int rc = true; 3723 struct v4l2_control control; 3724 3725 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME; 3726 control.value = 1; 3727 3728 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3729 if (rc) { 3730 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc); 3731 return false; 3732 } 3733 3734 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d", 3735 control.id, control.value); 3736 return true; 3737 } 3738 3739 bool venc_dev::venc_set_markltr() 3740 { 3741 DEBUG_PRINT_LOW("venc_set_goldenframe"); 3742 int rc = true; 3743 struct v4l2_control control; 3744 3745 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME; 3746 control.value = 1; 3747 3748 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3749 if (rc) { 3750 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc); 3751 return false; 3752 } 3753 3754 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d", 3755 control.id, control.value); 3756 return true; 3757 } 3758 3759 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle) 3760 { 3761 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle); 3762 struct v4l2_control control; 3763 int rc; 3764 struct v4l2_format fmt; 3765 struct v4l2_requestbuffers bufreq; 3766 3767 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION; 3768 if (rotation_angle == 0) 3769 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE; 3770 else if (rotation_angle == 90) 3771 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90; 3772 else if (rotation_angle == 180) 3773 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180; 3774 else if (rotation_angle == 270) 3775 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270; 3776 else { 3777 DEBUG_PRINT_ERROR("Failed to find valid rotation angle"); 3778 return false; 3779 } 3780 3781 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 3782 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3783 if (rc) { 3784 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control"); 3785 return false; 3786 } 3787 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 3788 3789 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3790 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 3791 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 3792 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 3793 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 3794 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 3795 return false; 3796 } 3797 3798 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 3799 bufreq.memory = V4L2_MEMORY_USERPTR; 3800 bufreq.count = m_sOutput_buff_property.actualcount; 3801 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3802 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 3803 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation"); 3804 return false; 3805 } 3806 if (bufreq.count >= m_sOutput_buff_property.mincount) 3807 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count; 3808 3809 return true; 3810 } 3811 3812 bool venc_dev::venc_set_searchrange() 3813 { 3814 DEBUG_PRINT_LOW("venc_set_searchrange"); 3815 struct v4l2_control control; 3816 struct v4l2_ext_control ctrl[6]; 3817 struct v4l2_ext_controls controls; 3818 int rc; 3819 3820 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 3821 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE; 3822 ctrl[0].value = 16; 3823 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE; 3824 ctrl[1].value = 4; 3825 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE; 3826 ctrl[2].value = 16; 3827 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE; 3828 ctrl[3].value = 4; 3829 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE; 3830 ctrl[4].value = 12; 3831 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE; 3832 ctrl[5].value = 4; 3833 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) || 3834 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) { 3835 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE; 3836 ctrl[0].value = 16; 3837 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE; 3838 ctrl[1].value = 4; 3839 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE; 3840 ctrl[2].value = 16; 3841 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE; 3842 ctrl[3].value = 4; 3843 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE; 3844 ctrl[4].value = 12; 3845 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE; 3846 ctrl[5].value = 4; 3847 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 3848 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE; 3849 ctrl[0].value = 4; 3850 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE; 3851 ctrl[1].value = 4; 3852 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE; 3853 ctrl[2].value = 4; 3854 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE; 3855 ctrl[3].value = 4; 3856 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE; 3857 ctrl[4].value = 4; 3858 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE; 3859 ctrl[5].value = 4; 3860 } else { 3861 DEBUG_PRINT_ERROR("Invalid codec type"); 3862 return false; 3863 } 3864 controls.count = 6; 3865 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 3866 controls.controls = ctrl; 3867 3868 DEBUG_PRINT_LOW(" Calling IOCTL set control for" 3869 "id=%x, val=%d id=%x, val=%d" 3870 "id=%x, val=%d id=%x, val=%d" 3871 "id=%x, val=%d id=%x, val=%d", 3872 controls.controls[0].id, controls.controls[0].value, 3873 controls.controls[1].id, controls.controls[1].value, 3874 controls.controls[2].id, controls.controls[2].value, 3875 controls.controls[3].id, controls.controls[3].value, 3876 controls.controls[4].id, controls.controls[4].value, 3877 controls.controls[5].id, controls.controls[5].value); 3878 3879 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 3880 if (rc) { 3881 DEBUG_PRINT_ERROR("Failed to set search range %d", rc); 3882 return false; 3883 } 3884 return true; 3885 } 3886 3887 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) 3888 { 3889 bool status = true; 3890 struct v4l2_control control; 3891 int rc = 0; 3892 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL; 3893 3894 switch (eControlRate) { 3895 case OMX_Video_ControlRateDisable: 3896 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF; 3897 break; 3898 case OMX_Video_ControlRateVariableSkipFrames: 3899 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR; 3900 break; 3901 case OMX_Video_ControlRateVariable: 3902 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR; 3903 break; 3904 case OMX_Video_ControlRateConstantSkipFrames: 3905 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR; 3906 break; 3907 case OMX_Video_ControlRateConstant: 3908 control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR; 3909 break; 3910 default: 3911 status = false; 3912 break; 3913 } 3914 3915 if (status) { 3916 3917 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3918 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3919 3920 if (rc) { 3921 DEBUG_PRINT_ERROR("Failed to set control"); 3922 return false; 3923 } 3924 3925 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3926 3927 rate_ctrl.rcmode = control.value; 3928 } 3929 3930 return status; 3931 } 3932 3933 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel) 3934 { 3935 bool status = true; 3936 struct v4l2_control control; 3937 int rc = 0; 3938 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 3939 3940 switch (ePerfLevel) { 3941 case OMX_QCOM_PerfLevelNominal: 3942 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 3943 break; 3944 case OMX_QCOM_PerfLevelTurbo: 3945 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 3946 break; 3947 default: 3948 status = false; 3949 break; 3950 } 3951 3952 if (status) { 3953 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3954 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3955 3956 if (rc) { 3957 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value); 3958 return false; 3959 } 3960 3961 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 3962 } 3963 return status; 3964 } 3965 3966 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable) 3967 { 3968 struct v4l2_control control; 3969 int rc = 0; 3970 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO; 3971 3972 if (enable) 3973 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED; 3974 else 3975 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED; 3976 3977 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 3978 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3979 if (rc) { 3980 DEBUG_PRINT_ERROR("Failed to set VUI timing info control"); 3981 return false; 3982 } 3983 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 3984 return true; 3985 } 3986 3987 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate) 3988 { 3989 struct v4l2_control control; 3990 int rc = 0; 3991 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK; 3992 control.value = nPeakBitrate; 3993 3994 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate); 3995 3996 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 3997 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 3998 3999 if (rc) { 4000 DEBUG_PRINT_ERROR("Failed to set peak bitrate control"); 4001 return false; 4002 } 4003 4004 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4005 4006 return true; 4007 } 4008 4009 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) 4010 { 4011 bool status = true; 4012 4013 if (eProfile == NULL || eLevel == NULL) { 4014 return false; 4015 } 4016 4017 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 4018 switch (codec_profile.profile) { 4019 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 4020 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4021 break; 4022 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 4023 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 4024 break; 4025 default: 4026 *eProfile = OMX_VIDEO_MPEG4ProfileMax; 4027 status = false; 4028 break; 4029 } 4030 4031 if (!status) { 4032 return status; 4033 } 4034 4035 //profile level 4036 switch (profile_level.level) { 4037 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: 4038 *eLevel = OMX_VIDEO_MPEG4Level0; 4039 break; 4040 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: 4041 *eLevel = OMX_VIDEO_MPEG4Level0b; 4042 break; 4043 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: 4044 *eLevel = OMX_VIDEO_MPEG4Level1; 4045 break; 4046 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: 4047 *eLevel = OMX_VIDEO_MPEG4Level2; 4048 break; 4049 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: 4050 *eLevel = OMX_VIDEO_MPEG4Level3; 4051 break; 4052 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: 4053 *eLevel = OMX_VIDEO_MPEG4Level4; 4054 break; 4055 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: 4056 *eLevel = OMX_VIDEO_MPEG4Level5; 4057 break; 4058 default: 4059 *eLevel = OMX_VIDEO_MPEG4LevelMax; 4060 status = false; 4061 break; 4062 } 4063 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 4064 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) { 4065 *eProfile = OMX_VIDEO_H263ProfileBaseline; 4066 } else { 4067 *eProfile = OMX_VIDEO_H263ProfileMax; 4068 return false; 4069 } 4070 4071 switch (profile_level.level) { 4072 case VEN_LEVEL_H263_10: 4073 *eLevel = OMX_VIDEO_H263Level10; 4074 break; 4075 case VEN_LEVEL_H263_20: 4076 *eLevel = OMX_VIDEO_H263Level20; 4077 break; 4078 case VEN_LEVEL_H263_30: 4079 *eLevel = OMX_VIDEO_H263Level30; 4080 break; 4081 case VEN_LEVEL_H263_40: 4082 *eLevel = OMX_VIDEO_H263Level40; 4083 break; 4084 case VEN_LEVEL_H263_45: 4085 *eLevel = OMX_VIDEO_H263Level45; 4086 break; 4087 case VEN_LEVEL_H263_50: 4088 *eLevel = OMX_VIDEO_H263Level50; 4089 break; 4090 case VEN_LEVEL_H263_60: 4091 *eLevel = OMX_VIDEO_H263Level60; 4092 break; 4093 case VEN_LEVEL_H263_70: 4094 *eLevel = OMX_VIDEO_H263Level70; 4095 break; 4096 default: 4097 *eLevel = OMX_VIDEO_H263LevelMax; 4098 status = false; 4099 break; 4100 } 4101 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4102 switch (codec_profile.profile) { 4103 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 4104 *eProfile = OMX_VIDEO_AVCProfileBaseline; 4105 break; 4106 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 4107 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 4108 break; 4109 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 4110 *eProfile = OMX_VIDEO_AVCProfileMain; 4111 break; 4112 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 4113 *eProfile = OMX_VIDEO_AVCProfileHigh; 4114 break; 4115 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 4116 *eProfile = OMX_VIDEO_AVCProfileExtended; 4117 break; 4118 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 4119 *eProfile = OMX_VIDEO_AVCProfileHigh10; 4120 break; 4121 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 4122 *eProfile = OMX_VIDEO_AVCProfileHigh422; 4123 break; 4124 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 4125 *eProfile = OMX_VIDEO_AVCProfileHigh444; 4126 break; 4127 default: 4128 *eProfile = OMX_VIDEO_AVCProfileMax; 4129 status = false; 4130 break; 4131 } 4132 4133 if (!status) { 4134 return status; 4135 } 4136 4137 switch (profile_level.level) { 4138 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 4139 *eLevel = OMX_VIDEO_AVCLevel1; 4140 break; 4141 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 4142 *eLevel = OMX_VIDEO_AVCLevel1b; 4143 break; 4144 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 4145 *eLevel = OMX_VIDEO_AVCLevel11; 4146 break; 4147 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 4148 *eLevel = OMX_VIDEO_AVCLevel12; 4149 break; 4150 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 4151 *eLevel = OMX_VIDEO_AVCLevel13; 4152 break; 4153 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 4154 *eLevel = OMX_VIDEO_AVCLevel2; 4155 break; 4156 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 4157 *eLevel = OMX_VIDEO_AVCLevel21; 4158 break; 4159 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 4160 *eLevel = OMX_VIDEO_AVCLevel22; 4161 break; 4162 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 4163 *eLevel = OMX_VIDEO_AVCLevel3; 4164 break; 4165 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 4166 *eLevel = OMX_VIDEO_AVCLevel31; 4167 break; 4168 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 4169 *eLevel = OMX_VIDEO_AVCLevel32; 4170 break; 4171 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 4172 *eLevel = OMX_VIDEO_AVCLevel4; 4173 break; 4174 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 4175 *eLevel = OMX_VIDEO_AVCLevel41; 4176 break; 4177 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 4178 *eLevel = OMX_VIDEO_AVCLevel42; 4179 break; 4180 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 4181 *eLevel = OMX_VIDEO_AVCLevel5; 4182 break; 4183 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 4184 *eLevel = OMX_VIDEO_AVCLevel51; 4185 break; 4186 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2: 4187 *eLevel = OMX_VIDEO_AVCLevel52; 4188 break; 4189 default : 4190 *eLevel = OMX_VIDEO_AVCLevelMax; 4191 status = false; 4192 break; 4193 } 4194 } 4195 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 4196 switch (codec_profile.profile) { 4197 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: 4198 *eProfile = OMX_VIDEO_VP8ProfileMain; 4199 break; 4200 default: 4201 *eProfile = OMX_VIDEO_VP8ProfileMax; 4202 status = false; 4203 break; 4204 } 4205 if (!status) { 4206 return status; 4207 } 4208 4209 switch (profile_level.level) { 4210 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: 4211 *eLevel = OMX_VIDEO_VP8Level_Version0; 4212 break; 4213 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: 4214 *eLevel = OMX_VIDEO_VP8Level_Version1; 4215 break; 4216 default: 4217 *eLevel = OMX_VIDEO_VP8LevelMax; 4218 status = false; 4219 break; 4220 } 4221 } 4222 4223 return status; 4224 } 4225 4226 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) 4227 { 4228 OMX_U32 new_profile = 0, new_level = 0; 4229 unsigned const int *profile_tbl = NULL; 4230 OMX_U32 mb_per_frame, mb_per_sec; 4231 bool profile_level_found = false; 4232 4233 DEBUG_PRINT_LOW("Init profile table for respective codec"); 4234 4235 //validate the ht,width,fps,bitrate and set the appropriate profile and level 4236 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 4237 if (*eProfile == 0) { 4238 if (!m_profile_set) { 4239 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4240 } else { 4241 switch (codec_profile.profile) { 4242 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 4243 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 4244 break; 4245 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 4246 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4247 break; 4248 default: 4249 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 4250 return false; 4251 } 4252 } 4253 } 4254 4255 if (*eLevel == 0 && !m_level_set) { 4256 *eLevel = OMX_VIDEO_MPEG4LevelMax; 4257 } 4258 4259 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 4260 profile_tbl = (unsigned int const *)mpeg4_profile_level_table; 4261 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 4262 profile_tbl = (unsigned int const *) 4263 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 4264 } else { 4265 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile); 4266 return false; 4267 } 4268 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4269 if (*eProfile == 0) { 4270 if (!m_profile_set) { 4271 *eProfile = OMX_VIDEO_AVCProfileBaseline; 4272 } else { 4273 switch (codec_profile.profile) { 4274 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 4275 *eProfile = OMX_VIDEO_AVCProfileBaseline; 4276 break; 4277 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 4278 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 4279 break; 4280 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 4281 *eProfile = OMX_VIDEO_AVCProfileMain; 4282 break; 4283 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 4284 *eProfile = OMX_VIDEO_AVCProfileExtended; 4285 break; 4286 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 4287 *eProfile = OMX_VIDEO_AVCProfileHigh; 4288 break; 4289 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 4290 *eProfile = OMX_VIDEO_AVCProfileHigh10; 4291 break; 4292 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 4293 *eProfile = OMX_VIDEO_AVCProfileHigh422; 4294 break; 4295 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 4296 *eProfile = OMX_VIDEO_AVCProfileHigh444; 4297 break; 4298 default: 4299 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 4300 return false; 4301 } 4302 } 4303 } 4304 4305 if (*eLevel == 0 && !m_level_set) { 4306 *eLevel = OMX_VIDEO_AVCLevelMax; 4307 } 4308 4309 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) || 4310 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) { 4311 profile_tbl = (unsigned int const *)h264_profile_level_table; 4312 } else if (*eProfile == OMX_VIDEO_AVCProfileHigh) { 4313 profile_tbl = (unsigned int const *) 4314 (&h264_profile_level_table[H264_HP_START]); 4315 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) { 4316 profile_tbl = (unsigned int const *) 4317 (&h264_profile_level_table[H264_MP_START]); 4318 } else { 4319 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile); 4320 return false; 4321 } 4322 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 4323 if (*eProfile == 0) { 4324 if (!m_profile_set) { 4325 *eProfile = OMX_VIDEO_H263ProfileBaseline; 4326 } else { 4327 switch (codec_profile.profile) { 4328 case VEN_PROFILE_H263_BASELINE: 4329 *eProfile = OMX_VIDEO_H263ProfileBaseline; 4330 break; 4331 default: 4332 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 4333 return false; 4334 } 4335 } 4336 } 4337 4338 if (*eLevel == 0 && !m_level_set) { 4339 *eLevel = OMX_VIDEO_H263LevelMax; 4340 } 4341 4342 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) { 4343 profile_tbl = (unsigned int const *)h263_profile_level_table; 4344 } else { 4345 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile); 4346 return false; 4347 } 4348 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 4349 if (*eProfile == 0) { 4350 *eProfile = OMX_VIDEO_VP8ProfileMain; 4351 } else { 4352 switch (codec_profile.profile) { 4353 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: 4354 *eProfile = OMX_VIDEO_VP8ProfileMain; 4355 break; 4356 default: 4357 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__); 4358 return false; 4359 } 4360 } 4361 if (*eLevel == 0) { 4362 switch (profile_level.level) { 4363 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: 4364 *eLevel = OMX_VIDEO_VP8Level_Version0; 4365 break; 4366 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: 4367 *eLevel = OMX_VIDEO_VP8Level_Version1; 4368 break; 4369 default: 4370 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__); 4371 return false; 4372 } 4373 } 4374 return true; 4375 } else { 4376 DEBUG_PRINT_LOW("Invalid codec type"); 4377 return false; 4378 } 4379 4380 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)* 4381 ((m_sVenc_cfg.dvs_width + 15)>> 4); 4382 4383 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) { 4384 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) 4385 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 4386 4387 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) 4388 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 4389 4390 { 4391 new_level = profile_level.level; 4392 new_profile = codec_profile.profile; 4393 return true; 4394 } 4395 } 4396 4397 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; 4398 4399 do { 4400 if (mb_per_frame <= (unsigned int)profile_tbl[0]) { 4401 if (mb_per_sec <= (unsigned int)profile_tbl[1]) { 4402 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) { 4403 new_level = (int)profile_tbl[3]; 4404 new_profile = (int)profile_tbl[4]; 4405 profile_level_found = true; 4406 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (unsigned int)new_profile, (unsigned int)new_level); 4407 break; 4408 } 4409 } 4410 } 4411 4412 profile_tbl = profile_tbl + 5; 4413 } while (profile_tbl[0] != 0); 4414 4415 if (profile_level_found != true) { 4416 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level"); 4417 return false; 4418 } 4419 4420 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) 4421 || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) { 4422 *eLevel = new_level; 4423 } 4424 4425 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u" 4426 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel); 4427 4428 return true; 4429 } 4430 #ifdef _ANDROID_ICS_ 4431 bool venc_dev::venc_set_meta_mode(bool mode) 4432 { 4433 metadatamode = mode; 4434 return true; 4435 } 4436 #endif 4437 4438 bool venc_dev::venc_is_video_session_supported(unsigned long width, 4439 unsigned long height) 4440 { 4441 if ((width * height < capability.min_width * capability.min_height) || 4442 (width * height > capability.max_width * capability.max_height)) { 4443 DEBUG_PRINT_ERROR( 4444 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)", 4445 width, height, capability.min_width, capability.min_height, 4446 capability.max_width, capability.max_height); 4447 return false; 4448 } 4449 4450 DEBUG_PRINT_LOW("video session supported"); 4451 return true; 4452 } 4453