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