1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010-2016, 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 <sys/eventfd.h> 33 #include <unistd.h> 34 #include <fcntl.h> 35 #include "video_encoder_device_v4l2.h" 36 #include "omx_video_encoder.h" 37 #include <media/msm_vidc.h> 38 #ifdef USE_ION 39 #include <linux/msm_ion.h> 40 #endif 41 #include <media/msm_media_info.h> 42 #include <cutils/properties.h> 43 #include <media/hardware/HardwareAPI.h> 44 45 #ifdef _ANDROID_ 46 #include <media/hardware/HardwareAPI.h> 47 #include <gralloc_priv.h> 48 #endif 49 50 #include <qdMetaData.h> 51 52 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1)) 53 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0) 54 #define MAXDPB 16 55 #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 56 #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 57 #define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1))) 58 #define MAX_PROFILE_PARAMS 6 59 #define MPEG4_SP_START 0 60 #define MPEG4_ASP_START (MPEG4_SP_START + 10) 61 #define H263_BP_START 0 62 #define H264_BP_START 0 63 #define H264_HP_START (H264_BP_START + 18) 64 #define H264_MP_START (H264_BP_START + 36) 65 #define HEVC_MAIN_START 0 66 #define HEVC_MAIN10_START (HEVC_MAIN_START + 13) 67 #define POLL_TIMEOUT 1000 68 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */ 69 70 #define SZ_4K 0x1000 71 #define SZ_1M 0x100000 72 73 /* MPEG4 profile and level table*/ 74 static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= { 75 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/ 76 {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0}, 77 {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0}, 78 {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0}, 79 {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0}, 80 {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0}, 81 {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0}, 82 {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0}, 83 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0}, 84 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0}, 85 /* Please update MPEG4_ASP_START accordingly, while adding new element */ 86 {0,0,0,0,0,0}, 87 88 {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 89 {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 90 {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 91 {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 92 {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 93 {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 94 {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 95 {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0}, 96 {0,0,0,0,0,0}, 97 }; 98 99 /* H264 profile and level table*/ 100 static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= { 101 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/ 102 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396}, 103 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396}, 104 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900}, 105 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376}, 106 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376}, 107 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376}, 108 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752}, 109 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100}, 110 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100}, 111 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000}, 112 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480}, 113 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768}, 114 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768}, 115 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816}, 116 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400}, 117 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320}, 118 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320}, 119 /* Please update H264_HP_START accordingly, while adding new element */ 120 {0,0,0,0,0,0}, 121 122 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396}, 123 {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396}, 124 {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900}, 125 {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376}, 126 {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376}, 127 {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376}, 128 {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752}, 129 {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100}, 130 {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100}, 131 {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000}, 132 {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480}, 133 {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768}, 134 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768}, 135 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816}, 136 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400}, 137 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320}, 138 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320}, 139 /* Please update H264_MP_START accordingly, while adding new element */ 140 {0,0,0,0,0,0}, 141 142 {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396}, 143 {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396}, 144 {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900}, 145 {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376}, 146 {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376}, 147 {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376}, 148 {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752}, 149 {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100}, 150 {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100}, 151 {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000}, 152 {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480}, 153 {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768}, 154 {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768}, 155 {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816}, 156 {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400}, 157 {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320}, 158 {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320}, 159 {0,0,0,0,0,0} 160 161 }; 162 163 /* H263 profile and level table*/ 164 static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= { 165 /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/ 166 {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0}, 167 {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0}, 168 {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0}, 169 {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0}, 170 {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0}, 171 {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0}, 172 {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0}, 173 {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0}, 174 {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0}, 175 {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0}, 176 {0,0,0,0,0,0} 177 }; 178 179 /* HEVC profile and level table*/ 180 static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= { 181 /*max mb per frame, max mb per sec, max bitrate, level, profile*/ 182 {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0}, 183 {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0}, 184 {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0}, 185 {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0}, 186 {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0}, 187 {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0}, 188 {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0}, 189 {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0}, 190 {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0}, 191 {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0}, 192 {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0}, 193 {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0}, 194 {138240,4147200,240000000,OMX_VIDEO_HEVCHighTierLevel52,OMX_VIDEO_HEVCProfileMain,0}, 195 /* Please update HEVC_MAIN_START accordingly, while adding new element */ 196 {0,0,0,0,0}, 197 198 {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0}, 199 {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0}, 200 {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0}, 201 {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0}, 202 {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0}, 203 {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0}, 204 {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0}, 205 {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0}, 206 {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0}, 207 {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0}, 208 {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0}, 209 {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0}, 210 {0,0,0,0,0}, 211 }; 212 213 214 #define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } 215 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } 216 217 #define BUFFER_LOG_LOC "/data/misc/media" 218 219 //constructor 220 venc_dev::venc_dev(class omx_venc *venc_class):mInputExtradata(venc_class), mOutputExtradata(venc_class) 221 { 222 //nothing to do 223 int i = 0; 224 venc_handle = venc_class; 225 etb = ebd = ftb = fbd = 0; 226 m_poll_efd = -1; 227 228 struct v4l2_control control; 229 for (i = 0; i < MAX_PORT; i++) 230 streaming[i] = false; 231 232 stopped = 1; 233 paused = false; 234 async_thread_created = false; 235 async_thread_force_stop = false; 236 color_format = 0; 237 hw_overload = false; 238 mBatchSize = 0; 239 pthread_mutex_init(&pause_resume_mlock, NULL); 240 pthread_cond_init(&pause_resume_cond, NULL); 241 memset(&idrperiod, 0, sizeof(idrperiod)); 242 memset(&multislice, 0, sizeof(multislice)); 243 memset (&slice_mode, 0 , sizeof(slice_mode)); 244 memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg)); 245 memset(&rate_ctrl, 0, sizeof(rate_ctrl)); 246 memset(&bitrate, 0, sizeof(bitrate)); 247 memset(&intra_period, 0, sizeof(intra_period)); 248 memset(&codec_profile, 0, sizeof(codec_profile)); 249 memset(&set_param, 0, sizeof(set_param)); 250 memset(&time_inc, 0, sizeof(time_inc)); 251 memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property)); 252 memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property)); 253 memset(&session_qp, 0, sizeof(session_qp)); 254 memset(&entropy, 0, sizeof(entropy)); 255 memset(&dbkfilter, 0, sizeof(dbkfilter)); 256 memset(&intra_refresh, 0, sizeof(intra_refresh)); 257 memset(&hec, 0, sizeof(hec)); 258 memset(&voptimecfg, 0, sizeof(voptimecfg)); 259 memset(&capability, 0, sizeof(capability)); 260 memset(&m_debug,0,sizeof(m_debug)); 261 memset(&hier_layers,0,sizeof(hier_layers)); 262 is_searchrange_set = false; 263 enable_mv_narrow_searchrange = false; 264 supported_rc_modes = RC_ALL; 265 memset(&vqzip_sei_info, 0, sizeof(vqzip_sei_info)); 266 memset(<rinfo, 0, sizeof(ltrinfo)); 267 memset(&fd_list, 0, sizeof(fd_list)); 268 memset(&hybrid_hp, 0, sizeof(hybrid_hp)); 269 sess_priority.priority = 1; //default to non-realtime 270 operating_rate = 0; 271 memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config)); 272 memset(&color_space, 0x0, sizeof(color_space)); 273 274 char property_value[PROPERTY_VALUE_MAX] = {0}; 275 property_get("vidc.enc.log.in", property_value, "0"); 276 m_debug.in_buffer_log = atoi(property_value); 277 278 property_get("vidc.enc.log.out", property_value, "0"); 279 m_debug.out_buffer_log = atoi(property_value); 280 281 property_get("vidc.enc.log.extradata", property_value, "0"); 282 m_debug.extradata_log = atoi(property_value); 283 284 property_get("vidc.enc.log.roiqp", property_value, "0"); 285 m_debug.roiqp_log = atoi(property_value); 286 #ifdef _UBWC_ 287 property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0"); 288 if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) || 289 !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) { 290 is_gralloc_source_ubwc = 0; 291 } else { 292 is_gralloc_source_ubwc = 1; 293 } 294 #else 295 is_gralloc_source_ubwc = 0; 296 #endif 297 298 property_get("persist.vidc.enc.csc.enable", property_value, "0"); 299 if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) || 300 !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) { 301 is_csc_enabled = 1; 302 } else { 303 is_csc_enabled = 0; 304 } 305 snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, 306 "%s", BUFFER_LOG_LOC); 307 } 308 309 venc_dev::~venc_dev() 310 { 311 } 312 313 void* venc_dev::async_venc_message_thread (void *input) 314 { 315 struct venc_msg venc_msg; 316 omx_video* omx_venc_base = NULL; 317 omx_venc *omx = reinterpret_cast<omx_venc*>(input); 318 omx_venc_base = reinterpret_cast<omx_video*>(input); 319 OMX_BUFFERHEADERTYPE* omxhdr = NULL; 320 321 prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); 322 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 323 struct pollfd pfds[2]; 324 struct v4l2_buffer v4l2_buf; 325 struct v4l2_event dqevent; 326 struct statistics stats; 327 pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; 328 pfds[1].events = POLLIN | POLLERR; 329 pfds[0].fd = omx->handle->m_nDriver_fd; 330 pfds[1].fd = omx->handle->m_poll_efd; 331 int error_code = 0,rc=0; 332 333 memset(&stats, 0, sizeof(statistics)); 334 memset(&v4l2_buf, 0, sizeof(v4l2_buf)); 335 336 while (!omx->handle->async_thread_force_stop) { 337 pthread_mutex_lock(&omx->handle->pause_resume_mlock); 338 339 if (omx->handle->paused) { 340 venc_msg.msgcode = VEN_MSG_PAUSE; 341 venc_msg.statuscode = VEN_S_SUCCESS; 342 343 if (omx->async_message_process(input, &venc_msg) < 0) { 344 DEBUG_PRINT_ERROR("ERROR: Failed to process pause msg"); 345 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 346 break; 347 } 348 349 /* Block here until the IL client resumes us again */ 350 pthread_cond_wait(&omx->handle->pause_resume_cond, 351 &omx->handle->pause_resume_mlock); 352 353 venc_msg.msgcode = VEN_MSG_RESUME; 354 venc_msg.statuscode = VEN_S_SUCCESS; 355 356 if (omx->async_message_process(input, &venc_msg) < 0) { 357 DEBUG_PRINT_ERROR("ERROR: Failed to process resume msg"); 358 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 359 break; 360 } 361 memset(&stats, 0, sizeof(statistics)); 362 } 363 364 pthread_mutex_unlock(&omx->handle->pause_resume_mlock); 365 366 rc = poll(pfds, 2, POLL_TIMEOUT); 367 368 if (!rc) { 369 DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d", 370 omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd); 371 continue; 372 } else if (rc < 0 && errno != EINTR && errno != EAGAIN) { 373 DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno); 374 break; 375 } 376 377 if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) { 378 DEBUG_PRINT_ERROR("async_venc_message_thread interrupted to be exited"); 379 break; 380 } 381 382 if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) { 383 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 384 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 385 v4l2_buf.length = omx->handle->num_output_planes; 386 v4l2_buf.m.planes = plane; 387 388 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 389 venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE; 390 venc_msg.statuscode=VEN_S_SUCCESS; 391 omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index; 392 int extra_idx = EXTRADATA_IDX(v4l2_buf.length); 393 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 394 omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr; 395 } else { 396 omxhdr->pPlatformPrivate = 0; 397 } 398 venc_msg.buf.len= v4l2_buf.m.planes->bytesused; 399 venc_msg.buf.offset = v4l2_buf.m.planes->data_offset; 400 venc_msg.buf.flags = 0; 401 venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer; 402 venc_msg.buf.clientdata=(void*)omxhdr; 403 venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec; 404 405 /* TODO: ideally report other types of frames as well 406 * for now it doesn't look like IL client cares about 407 * other types 408 */ 409 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) 410 venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR; 411 412 if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) 413 venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME; 414 415 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG) 416 venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG; 417 418 if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_EOS) 419 venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS; 420 421 if (omx->handle->num_output_planes > 1 && v4l2_buf.m.planes->bytesused) 422 venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA; 423 424 if (omxhdr->nFilledLen) 425 venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME; 426 427 omx->handle->fbd++; 428 stats.bytes_generated += venc_msg.buf.len; 429 430 if (omx->async_message_process(input,&venc_msg) < 0) { 431 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 432 break; 433 } 434 } 435 } 436 437 if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) { 438 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 439 v4l2_buf.memory = V4L2_MEMORY_USERPTR; 440 v4l2_buf.m.planes = plane; 441 v4l2_buf.length = omx->handle->num_input_planes; 442 443 while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) { 444 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE; 445 venc_msg.statuscode=VEN_S_SUCCESS; 446 omx->handle->ebd++; 447 448 if (omx->handle->mBatchSize) { 449 int bufIndex = omx->handle->mBatchInfo.retrieveBufferAt(v4l2_buf.index); 450 if (bufIndex < 0) { 451 DEBUG_PRINT_ERROR("Retrieved invalid buffer %d", v4l2_buf.index); 452 break; 453 } 454 if (omx->handle->mBatchInfo.isPending(bufIndex)) { 455 DEBUG_PRINT_LOW(" EBD for %d [v4l2-id=%d].. batch still pending", 456 bufIndex, v4l2_buf.index); 457 //do not return to client yet 458 continue; 459 } 460 v4l2_buf.index = bufIndex; 461 } 462 if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion) 463 omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index]; 464 else 465 omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index]; 466 467 int extra_idx = EXTRADATA_IDX(v4l2_buf.length); 468 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 469 omxhdr->pPlatformPrivate = (void *)v4l2_buf.m.planes[extra_idx].m.userptr; 470 omx->handle->mInputExtradata.put((char *)omxhdr->pPlatformPrivate); 471 } else { 472 omxhdr->pPlatformPrivate = 0; 473 } 474 475 venc_msg.buf.clientdata=(void*)omxhdr; 476 477 DEBUG_PRINT_LOW("sending EBD %p [id=%d]", omxhdr, v4l2_buf.index); 478 if (omx->async_message_process(input,&venc_msg) < 0) { 479 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 480 break; 481 } 482 } 483 } 484 485 if (pfds[0].revents & POLLPRI) { 486 rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent); 487 488 if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { 489 venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE; 490 venc_msg.statuscode = VEN_S_SUCCESS; 491 492 if (omx->async_message_process(input,&venc_msg) < 0) { 493 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 494 break; 495 } 496 497 venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE; 498 venc_msg.statuscode = VEN_S_SUCCESS; 499 500 if (omx->async_message_process(input,&venc_msg) < 0) { 501 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 502 break; 503 } 504 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) { 505 DEBUG_PRINT_ERROR("HW Overload received"); 506 venc_msg.statuscode = VEN_S_EFAIL; 507 venc_msg.msgcode = VEN_MSG_HW_OVERLOAD; 508 509 if (omx->async_message_process(input,&venc_msg) < 0) { 510 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 511 break; 512 } 513 } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){ 514 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state"); 515 venc_msg.msgcode = VEN_MSG_INDICATION; 516 venc_msg.statuscode=VEN_S_EFAIL; 517 518 if (omx->async_message_process(input,&venc_msg) < 0) { 519 DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message"); 520 break; 521 } 522 } 523 } 524 525 /* calc avg. fps, bitrate */ 526 struct timeval tv; 527 gettimeofday(&tv,NULL); 528 OMX_U64 time_diff = (OMX_U32)((tv.tv_sec * 1000000 + tv.tv_usec) - 529 (stats.prev_tv.tv_sec * 1000000 + stats.prev_tv.tv_usec)); 530 if (time_diff >= 5000000) { 531 if (stats.prev_tv.tv_sec) { 532 OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd; 533 float framerate = num_fbd * 1000000/(float)time_diff; 534 OMX_U32 bitrate = (stats.bytes_generated * 8/num_fbd) * framerate; 535 DEBUG_PRINT_HIGH("stats: avg. fps %0.2f, bitrate %d", 536 framerate, bitrate); 537 } 538 stats.prev_tv = tv; 539 stats.bytes_generated = 0; 540 stats.prev_fbd = omx->handle->fbd; 541 } 542 543 } 544 545 DEBUG_PRINT_HIGH("omx_venc: Async Thread exit"); 546 return NULL; 547 } 548 549 static const int event_type[] = { 550 V4L2_EVENT_MSM_VIDC_FLUSH_DONE, 551 V4L2_EVENT_MSM_VIDC_SYS_ERROR 552 }; 553 554 static OMX_ERRORTYPE subscribe_to_events(int fd) 555 { 556 OMX_ERRORTYPE eRet = OMX_ErrorNone; 557 struct v4l2_event_subscription sub; 558 int array_sz = sizeof(event_type)/sizeof(int); 559 int i,rc; 560 memset(&sub, 0, sizeof(sub)); 561 562 if (fd < 0) { 563 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 564 return OMX_ErrorBadParameter; 565 } 566 567 for (i = 0; i < array_sz; ++i) { 568 memset(&sub, 0, sizeof(sub)); 569 sub.type = event_type[i]; 570 rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 571 572 if (rc) { 573 DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type); 574 break; 575 } 576 } 577 578 if (i < array_sz) { 579 for (--i; i >=0 ; i--) { 580 memset(&sub, 0, sizeof(sub)); 581 sub.type = event_type[i]; 582 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 583 584 if (rc) 585 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 586 } 587 588 eRet = OMX_ErrorNotImplemented; 589 } 590 591 return eRet; 592 } 593 594 int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src) 595 { 596 OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst; 597 598 if (!dst || !src) 599 return 0; 600 601 /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those 602 * targets, since the payload format will be different */ 603 mbi->nFormat = 1; 604 mbi->nDataSize = src->data_size; 605 memcpy(&mbi->data, &src->data, src->data_size); 606 607 return mbi->nDataSize + sizeof(*mbi); 608 } 609 610 bool venc_dev::handle_input_extradata(void *buffer, int fd) 611 { 612 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer; 613 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 614 ssize_t consumed_len = 0; 615 int enable = 0, i = 0; 616 int height = 0, width = 0; 617 char *userptr; 618 int extra_fd; 619 unsigned offset; 620 ssize_t extra_size; 621 struct v4l2_control control; 622 623 memset(&control, 0, sizeof(control)); 624 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 625 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &control) < 0) { 626 return false; 627 } 628 629 if (!(control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS || 630 control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI || 631 control.value == V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP || 632 control.value == V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP)) { 633 DEBUG_PRINT_LOW("Input extradata not enabled"); 634 return true; 635 } 636 637 /* 638 * At this point encoder component doesn't know where the extradata is 639 * located in YUV buffer. For all practical usecases, decoder appends 640 * extradata after nFilledLen which is calcualted as 32 aligned height 641 * and width * 3 / 2. Hence start looking for extradata from this point. 642 */ 643 644 height = ALIGN(m_sVenc_cfg.input_height, 32); 645 width = ALIGN(m_sVenc_cfg.input_width, 32); 646 647 int rc = mInputExtradata.get(buffer, &userptr, &extra_fd, &offset, &extra_size); 648 if (rc != OMX_ErrorNone) { 649 DEBUG_PRINT_ERROR("Unable to get extradata memory 4"); 650 return false; 651 } 652 unsigned char *pVirt; 653 int size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); 654 pVirt= (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0); 655 656 p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned long)(pVirt + ((width * height * 3) / 2) + 3)&(~3)); 657 char *p_extradata = userptr; 658 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; 659 if (p_extra) { 660 while ((consumed_len < extra_size) 661 && (p_extra->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) { 662 DEBUG_PRINT_LOW("Extradata Type = 0x%x", (OMX_QCOM_EXTRADATATYPE)p_extra->eType); 663 switch ((OMX_QCOM_EXTRADATATYPE)p_extra->eType) { 664 case OMX_ExtraDataFrameDimension: 665 { 666 struct msm_vidc_extradata_index *payload; 667 OMX_QCOM_EXTRADATA_FRAMEDIMENSION *framedimension_format; 668 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_extradata_index) + 3)&(~3); 669 data->nVersion.nVersion = OMX_SPEC_VERSION; 670 data->nPortIndex = 0; 671 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_INDEX; 672 data->nDataSize = sizeof(struct msm_vidc_input_crop_payload); 673 framedimension_format = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)p_extra->data; 674 payload = (struct msm_vidc_extradata_index *)(data->data); 675 payload->type = (msm_vidc_extradata_type)MSM_VIDC_EXTRADATA_INPUT_CROP; 676 payload->input_crop.left = framedimension_format->nDecWidth; 677 payload->input_crop.top = framedimension_format->nDecHeight; 678 payload->input_crop.width = framedimension_format->nActualWidth; 679 payload->input_crop.height = framedimension_format->nActualHeight; 680 DEBUG_PRINT_LOW("Height = %d Width = %d Actual Height = %d Actual Width = %d", 681 framedimension_format->nDecWidth, framedimension_format->nDecHeight, 682 framedimension_format->nActualWidth, framedimension_format->nActualHeight); 683 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 684 break; 685 } 686 case OMX_ExtraDataQP: 687 { 688 OMX_QCOM_EXTRADATA_QP * qp_payload = NULL; 689 struct msm_vidc_frame_qp_payload *payload; 690 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_frame_qp_payload) + 3)&(~3); 691 data->nVersion.nVersion = OMX_SPEC_VERSION; 692 data->nPortIndex = 0; 693 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_FRAME_QP; 694 data->nDataSize = sizeof(struct msm_vidc_frame_qp_payload); 695 qp_payload = (OMX_QCOM_EXTRADATA_QP *)p_extra->data; 696 payload = (struct msm_vidc_frame_qp_payload *)(data->data); 697 payload->frame_qp = qp_payload->nQP; 698 DEBUG_PRINT_LOW("Frame QP = %d", payload->frame_qp); 699 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 700 break; 701 } 702 case OMX_ExtraDataVQZipSEI: 703 DEBUG_PRINT_LOW("VQZIP SEI Found "); 704 mInputExtradata.vqzip_sei_found = true; 705 break; 706 default: 707 break; 708 } 709 consumed_len += p_extra->nSize; 710 p_extra = (OMX_OTHER_EXTRADATATYPE *)((char *)p_extra + p_extra->nSize); 711 } 712 713 if (control.value == V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS || 714 control.value == V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI) { 715 if (!mInputExtradata.vqzip_sei_found) { 716 DEBUG_PRINT_ERROR("VQZIP is enabled, But no VQZIP SEI found. Rejecting the session"); 717 munmap(pVirt, size); 718 mInputExtradata.put(userptr); 719 return false; 720 } 721 #ifdef _VQZIP_ 722 data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct VQZipStats) + 3)&(~3); 723 data->nVersion.nVersion = OMX_SPEC_VERSION; 724 data->nPortIndex = 0; 725 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_YUVSTATS_INFO; 726 data->nDataSize = sizeof(struct VQZipStats); 727 vqzip.fill_stats_data((void*)pVirt, (void*) data->data); 728 data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 729 #endif 730 } 731 732 data->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); 733 data->nVersion.nVersion = OMX_SPEC_VERSION; 734 data->eType = OMX_ExtraDataNone; 735 data->nDataSize = 0; 736 data->data[0] = 0; 737 738 } 739 munmap(pVirt, size); 740 mInputExtradata.put(userptr); 741 return true; 742 } 743 744 bool venc_dev::handle_output_extradata(void *buffer) 745 { 746 OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer; 747 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 748 char *extradata_uaddr = (char *)p_bufhdr->pPlatformPrivate; 749 750 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer + 751 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4); 752 753 if (mOutputExtradata.getBufferSize() > 754 (ssize_t)(p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4))) { 755 DEBUG_PRINT_ERROR("Insufficient buffer size for extradata"); 756 p_extra = NULL; 757 return false; 758 } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) { 759 /* A lot of the code below assumes this condition, so error out if it's not met */ 760 DEBUG_PRINT_ERROR("Extradata ABI mismatch"); 761 return false; 762 } 763 764 struct msm_vidc_extradata_header *p_extradata = NULL; 765 do { 766 p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ? 767 ((char *)p_extradata) + p_extradata->size : extradata_uaddr); 768 769 switch (p_extradata->type) { 770 case MSM_VIDC_EXTRADATA_METADATA_MBI: 771 { 772 OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata); 773 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4); 774 p_extra->nVersion.nVersion = OMX_SPEC_VERSION; 775 p_extra->nPortIndex = OMX_DirOutput; 776 p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo; 777 p_extra->nDataSize = payloadSize; 778 break; 779 } 780 case MSM_VIDC_EXTRADATA_METADATA_LTR: 781 { 782 *p_extra->data = *p_extradata->data; 783 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4); 784 p_extra->nVersion.nVersion = OMX_SPEC_VERSION; 785 p_extra->nPortIndex = OMX_DirOutput; 786 p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo; 787 p_extra->nDataSize = p_extradata->data_size; 788 break; 789 } 790 case MSM_VIDC_EXTRADATA_NONE: 791 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4); 792 p_extra->nVersion.nVersion = OMX_SPEC_VERSION; 793 p_extra->nPortIndex = OMX_DirOutput; 794 p_extra->eType = OMX_ExtraDataNone; 795 p_extra->nDataSize = 0; 796 break; 797 default: 798 /* No idea what this stuff is, just skip over it */ 799 DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it", 800 p_extradata->type); 801 continue; 802 } 803 804 p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize); 805 } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE); 806 807 /* Just for debugging: Traverse the list of extra datas and spit it out onto log */ 808 p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer + 809 p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4); 810 while(p_extra->eType != OMX_ExtraDataNone) 811 { 812 DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p", 813 p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType, 814 (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra); 815 816 p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + 817 p_extra->nSize); 818 } 819 mOutputExtradata.put(extradata_uaddr); 820 return true; 821 } 822 823 int venc_dev::venc_set_format(int format) 824 { 825 int rc = true; 826 827 if (format) { 828 color_format = format; 829 830 switch (color_format) { 831 case NV12_128m: 832 return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m); 833 default: 834 return false; 835 } 836 837 } else { 838 color_format = 0; 839 rc = false; 840 } 841 842 return rc; 843 } 844 845 bool venc_dev::venc_get_output_log_flag() 846 { 847 return (m_debug.out_buffer_log == 1); 848 } 849 850 int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len) 851 { 852 if (venc_handle->is_secure_session()) { 853 DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!"); 854 return -1; 855 } 856 857 if (!m_debug.outfile) { 858 int size = 0; 859 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 860 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v", 861 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 862 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 863 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264", 864 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 865 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 866 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265", 867 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 868 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 869 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263", 870 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 871 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 872 size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf", 873 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 874 } 875 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 876 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d", 877 m_debug.outfile_name, size); 878 } 879 m_debug.outfile = fopen(m_debug.outfile_name, "ab"); 880 if (!m_debug.outfile) { 881 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d", 882 m_debug.outfile_name, errno); 883 m_debug.outfile_name[0] = '\0'; 884 return -1; 885 } 886 } 887 if (m_debug.outfile && buffer_len) { 888 DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len); 889 fwrite(buffer_addr, buffer_len, 1, m_debug.outfile); 890 } 891 return 0; 892 } 893 894 int venc_dev::venc_extradata_log_buffers(char *buffer_addr) 895 { 896 if (!m_debug.extradatafile && m_debug.extradata_log) { 897 int size = 0; 898 if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 899 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.m4v", 900 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 901 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 902 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264", 903 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 904 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 905 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265", 906 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 907 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 908 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263", 909 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 910 } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 911 size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.ivf", 912 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 913 } 914 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 915 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d", 916 m_debug.extradatafile_name, size); 917 } 918 919 m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab"); 920 if (!m_debug.extradatafile) { 921 DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d", 922 m_debug.extradatafile_name, errno); 923 m_debug.extradatafile_name[0] = '\0'; 924 return -1; 925 } 926 } 927 928 if (m_debug.extradatafile) { 929 OMX_OTHER_EXTRADATATYPE *p_extra = NULL; 930 do { 931 p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr : 932 ((char *)p_extra) + p_extra->nSize); 933 fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile); 934 } while (p_extra->eType != OMX_ExtraDataNone); 935 } 936 return 0; 937 } 938 939 int venc_dev::venc_roiqp_log_buffers(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) { 940 int size = 0; 941 if (!roiInfo || !m_debug.roiqp_log) { 942 DEBUG_PRINT_LOW("Nothing to log"); 943 return 0; 944 } 945 if (!m_debug.roiqpfile) { 946 size = snprintf(m_debug.roiqpfile_name, PROPERTY_VALUE_MAX, "%s/enc_%lu_%lu_%p.roiqp", 947 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 948 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 949 DEBUG_PRINT_ERROR("Failed to open ROIQP file: %s for logging size:%d", 950 m_debug.roiqpfile_name, size); 951 m_debug.roiqpfile_name[0] = '\0'; 952 return -1; 953 } 954 m_debug.roiqpfile = fopen(m_debug.roiqpfile_name, "ab"); 955 if (!m_debug.roiqpfile) { 956 DEBUG_PRINT_ERROR("Failed to open ROI QP file: %s for logging errno:%d", 957 m_debug.roiqpfile_name, errno); 958 m_debug.roiqpfile_name[0] = '\0'; 959 return -1; 960 } 961 } 962 if (m_debug.roiqpfile) { 963 if (fwrite(&mInputExtradata.mDbgEtbCount, sizeof(mInputExtradata.mDbgEtbCount), 1, m_debug.roiqpfile) != 1) { 964 DEBUG_PRINT_ERROR("Unable to write to QP file"); 965 return -1; 966 } 967 if (fwrite(&roiInfo->nLowerQpOffset, sizeof(roiInfo->nLowerQpOffset), 1, m_debug.roiqpfile) != 1) { 968 DEBUG_PRINT_ERROR("Unable to write to QP file"); 969 return -1; 970 } 971 if (fwrite(&roiInfo->nUpperQpOffset, sizeof(roiInfo->nUpperQpOffset), 1, m_debug.roiqpfile) != 1) { 972 DEBUG_PRINT_ERROR("Unable to write to QP file"); 973 return -1; 974 } 975 if (fwrite((char *)roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize, 1, m_debug.roiqpfile) != 1) { 976 DEBUG_PRINT_ERROR("Unable to write to QP file"); 977 return -1; 978 } 979 } 980 return 0; 981 } 982 983 int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset, 984 unsigned long inputformat) { 985 if (venc_handle->is_secure_session()) { 986 DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!"); 987 return -1; 988 } 989 990 if (!m_debug.infile) { 991 int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv", 992 m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this); 993 if ((size > PROPERTY_VALUE_MAX) && (size < 0)) { 994 DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d", 995 m_debug.infile_name, size); 996 } 997 m_debug.infile = fopen (m_debug.infile_name, "ab"); 998 if (!m_debug.infile) { 999 DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name); 1000 m_debug.infile_name[0] = '\0'; 1001 return -1; 1002 } 1003 } 1004 1005 if (m_debug.infile && pbuffer && pbuffer->nFilledLen) { 1006 int stride, scanlines; 1007 int color_format; 1008 unsigned long i, msize; 1009 unsigned char *pvirt = NULL, *ptemp = NULL; 1010 unsigned char *temp = (unsigned char *)pbuffer->pBuffer; 1011 1012 switch (inputformat) { 1013 case V4L2_PIX_FMT_NV12: 1014 color_format = COLOR_FMT_NV12; 1015 break; 1016 case V4L2_PIX_FMT_NV12_UBWC: 1017 color_format = COLOR_FMT_NV12_UBWC; 1018 break; 1019 case V4L2_PIX_FMT_RGB32: 1020 color_format = COLOR_FMT_RGBA8888; 1021 break; 1022 case V4L2_PIX_FMT_RGBA8888_UBWC: 1023 color_format = COLOR_FMT_RGBA8888_UBWC; 1024 break; 1025 default: 1026 color_format = COLOR_FMT_NV12; 1027 DEBUG_PRINT_LOW("Default format NV12 is set for logging [%lu]", inputformat); 1028 break; 1029 } 1030 1031 msize = VENUS_BUFFER_SIZE(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height); 1032 const unsigned int extra_size = VENUS_EXTRADATA_SIZE(m_sVenc_cfg.input_width, m_sVenc_cfg.input_height); 1033 1034 if (metadatamode == 1) { 1035 pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset); 1036 if (pvirt == MAP_FAILED) { 1037 DEBUG_PRINT_ERROR("%s mmap failed", __func__); 1038 return -1; 1039 } 1040 ptemp = pvirt; 1041 } else { 1042 ptemp = temp; 1043 } 1044 1045 if (color_format == COLOR_FMT_NV12) { 1046 stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width); 1047 scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height); 1048 1049 for (i = 0; i < m_sVenc_cfg.input_height; i++) { 1050 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile); 1051 ptemp += stride; 1052 } 1053 if (metadatamode == 1) { 1054 ptemp = pvirt + (stride * scanlines); 1055 } else { 1056 ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines); 1057 } 1058 for (i = 0; i < m_sVenc_cfg.input_height/2; i++) { 1059 fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile); 1060 ptemp += stride; 1061 } 1062 } else if (color_format == COLOR_FMT_RGBA8888) { 1063 stride = VENUS_RGB_STRIDE(color_format, m_sVenc_cfg.input_width); 1064 scanlines = VENUS_RGB_SCANLINES(color_format, m_sVenc_cfg.input_height); 1065 1066 for (i = 0; i < m_sVenc_cfg.input_height; i++) { 1067 fwrite(ptemp, m_sVenc_cfg.input_width * 4, 1, m_debug.infile); 1068 ptemp += stride; 1069 } 1070 } else if (color_format == COLOR_FMT_NV12_UBWC || color_format == COLOR_FMT_RGBA8888_UBWC) { 1071 if (color_format == COLOR_FMT_NV12_UBWC) { 1072 msize -= 2 * extra_size; 1073 } 1074 fwrite(ptemp, msize, 1, m_debug.infile); 1075 } 1076 1077 if (metadatamode == 1 && pvirt) { 1078 munmap(pvirt, msize); 1079 } 1080 } 1081 1082 return 0; 1083 } 1084 1085 bool venc_dev::venc_open(OMX_U32 codec) 1086 { 1087 int r; 1088 unsigned int alignment = 0,buffer_size = 0, temp =0; 1089 struct v4l2_control control; 1090 OMX_STRING device_name = (OMX_STRING)"/dev/video33"; 1091 char property_value[PROPERTY_VALUE_MAX] = {0}; 1092 char platform_name[PROPERTY_VALUE_MAX] = {0}; 1093 FILE *soc_file = NULL; 1094 char buffer[10]; 1095 1096 property_get("ro.board.platform", platform_name, "0"); 1097 property_get("vidc.enc.narrow.searchrange", property_value, "0"); 1098 enable_mv_narrow_searchrange = atoi(property_value); 1099 1100 if (!strncmp(platform_name, "msm8610", 7)) { 1101 device_name = (OMX_STRING)"/dev/video/q6_enc"; 1102 supported_rc_modes = (RC_ALL & ~RC_CBR_CFR); 1103 } 1104 m_nDriver_fd = open (device_name, O_RDWR); 1105 if ((int)m_nDriver_fd < 0) { 1106 DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure"); 1107 return false; 1108 } 1109 m_poll_efd = eventfd(0, 0); 1110 if (m_poll_efd < 0) { 1111 DEBUG_PRINT_ERROR("Failed to open event fd(%s)", strerror(errno)); 1112 return false; 1113 } 1114 DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)m_nDriver_fd); 1115 1116 // set the basic configuration of the video encoder driver 1117 m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; 1118 m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; 1119 m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; 1120 m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; 1121 m_sVenc_cfg.fps_num = 30; 1122 m_sVenc_cfg.fps_den = 1; 1123 m_sVenc_cfg.targetbitrate = 64000; 1124 m_sVenc_cfg.inputformat= V4L2_DEFAULT_OUTPUT_COLOR_FMT; 1125 1126 m_codec = codec; 1127 1128 if (codec == OMX_VIDEO_CodingMPEG4) { 1129 m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4; 1130 codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; 1131 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; 1132 session_qp_range.minqp = 1; 1133 session_qp_range.maxqp = 31; 1134 } else if (codec == OMX_VIDEO_CodingH263) { 1135 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263; 1136 codec_profile.profile = VEN_PROFILE_H263_BASELINE; 1137 profile_level.level = VEN_LEVEL_H263_20; 1138 session_qp_range.minqp = 1; 1139 session_qp_range.maxqp = 31; 1140 } else if (codec == OMX_VIDEO_CodingAVC) { 1141 m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264; 1142 codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; 1143 profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; 1144 session_qp_range.minqp = 1; 1145 session_qp_range.maxqp = 51; 1146 } else if (codec == OMX_VIDEO_CodingVP8) { 1147 m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8; 1148 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; 1149 profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; 1150 session_qp_range.minqp = 1; 1151 session_qp_range.maxqp = 128; 1152 } else if (codec == OMX_VIDEO_CodingHEVC) { 1153 m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC; 1154 session_qp_range.minqp = 1; 1155 session_qp_range.maxqp = 51; 1156 codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN; 1157 profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1; 1158 } 1159 session_qp_values.minqp = session_qp_range.minqp; 1160 session_qp_values.maxqp = session_qp_range.maxqp; 1161 1162 int ret; 1163 ret = subscribe_to_events(m_nDriver_fd); 1164 1165 if (ret) { 1166 DEBUG_PRINT_ERROR("Subscribe Event Failed"); 1167 return false; 1168 } 1169 1170 struct v4l2_fmtdesc fdesc; 1171 struct v4l2_format fmt; 1172 struct v4l2_requestbuffers bufreq; 1173 struct v4l2_capability cap; 1174 1175 ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap); 1176 1177 if (ret) { 1178 DEBUG_PRINT_ERROR("Failed to query capabilities"); 1179 } else { 1180 DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," 1181 " version = %d, capabilities = %x", cap.driver, cap.card, 1182 cap.bus_info, cap.version, cap.capabilities); 1183 } 1184 1185 ret=0; 1186 fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1187 fdesc.index=0; 1188 1189 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 1190 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 1191 fdesc.pixelformat, fdesc.flags); 1192 fdesc.index++; 1193 } 1194 1195 fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1196 fdesc.index=0; 1197 1198 while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { 1199 DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x", fdesc.description, 1200 fdesc.pixelformat, fdesc.flags); 1201 fdesc.index++; 1202 } 1203 1204 is_thulium_v1 = false; 1205 soc_file= fopen("/sys/devices/soc0/soc_id", "r"); 1206 if (soc_file) { 1207 fread(buffer, 1, 4, soc_file); 1208 fclose(soc_file); 1209 if (atoi(buffer) == 246) { 1210 soc_file = fopen("/sys/devices/soc0/revision", "r"); 1211 if (soc_file) { 1212 fread(buffer, 1, 4, soc_file); 1213 fclose(soc_file); 1214 if (atoi(buffer) == 1) { 1215 is_thulium_v1 = true; 1216 DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE"); 1217 } 1218 } 1219 } 1220 } 1221 1222 if (venc_handle->is_secure_session()) { 1223 m_sOutput_buff_property.alignment = SZ_1M; 1224 m_sInput_buff_property.alignment = SZ_1M; 1225 } else { 1226 m_sOutput_buff_property.alignment = SZ_4K; 1227 m_sInput_buff_property.alignment = SZ_4K; 1228 } 1229 1230 memset(&fmt, 0, sizeof(fmt)); 1231 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1232 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1233 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1234 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1235 1236 /*TODO: Return values not handled properly in this function anywhere. 1237 * Need to handle those.*/ 1238 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 1239 1240 if (ret) { 1241 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 1242 return false; 1243 } 1244 1245 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1246 1247 memset(&fmt, 0, sizeof(fmt)); 1248 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1249 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 1250 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 1251 fmt.fmt.pix_mp.pixelformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT; 1252 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; 1253 1254 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 1255 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1256 1257 bufreq.memory = V4L2_MEMORY_USERPTR; 1258 bufreq.count = 2; 1259 1260 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1261 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 1262 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 1263 1264 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1265 bufreq.count = 2; 1266 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 1267 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 1268 1269 if(venc_handle->is_secure_session()) { 1270 control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; 1271 control.value = 1; 1272 DEBUG_PRINT_HIGH("ioctl: open secure device"); 1273 ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control); 1274 if (ret) { 1275 DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret); 1276 return false; 1277 } 1278 } 1279 1280 resume_in_stopped = 0; 1281 metadatamode = 0; 1282 1283 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; 1284 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; 1285 1286 DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d", control.id, control.value); 1287 1288 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) 1289 DEBUG_PRINT_ERROR("Failed to set control"); 1290 1291 struct v4l2_frmsizeenum frmsize; 1292 1293 //Get the hardware capabilities 1294 memset((void *)&frmsize,0,sizeof(frmsize)); 1295 frmsize.index = 0; 1296 frmsize.pixel_format = m_sVenc_cfg.codectype; 1297 ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize); 1298 1299 if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { 1300 DEBUG_PRINT_ERROR("Failed to get framesizes"); 1301 return false; 1302 } 1303 1304 if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 1305 capability.min_width = frmsize.stepwise.min_width; 1306 capability.max_width = frmsize.stepwise.max_width; 1307 capability.min_height = frmsize.stepwise.min_height; 1308 capability.max_height = frmsize.stepwise.max_height; 1309 } 1310 1311 //Initialize non-default parameters 1312 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 1313 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 1314 control.value = 0x7fffffff; 1315 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) 1316 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n"); 1317 } 1318 1319 property_get("vidc.debug.turbo", property_value, "0"); 1320 if (atoi(property_value)) { 1321 DEBUG_PRINT_HIGH("Turbo mode debug property enabled"); 1322 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 1323 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 1324 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 1325 DEBUG_PRINT_ERROR("Failed to set turbo mode"); 1326 } 1327 } 1328 return true; 1329 } 1330 1331 1332 static OMX_ERRORTYPE unsubscribe_to_events(int fd) 1333 { 1334 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1335 struct v4l2_event_subscription sub; 1336 int array_sz = sizeof(event_type)/sizeof(int); 1337 int i,rc; 1338 1339 if (fd < 0) { 1340 DEBUG_PRINT_ERROR("Invalid input: %d", fd); 1341 return OMX_ErrorBadParameter; 1342 } 1343 1344 for (i = 0; i < array_sz; ++i) { 1345 memset(&sub, 0, sizeof(sub)); 1346 sub.type = event_type[i]; 1347 rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 1348 1349 if (rc) { 1350 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type); 1351 break; 1352 } 1353 } 1354 1355 return eRet; 1356 } 1357 1358 void venc_dev::venc_close() 1359 { 1360 DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd); 1361 1362 if ((int)m_nDriver_fd >= 0) { 1363 DEBUG_PRINT_HIGH("venc_close E"); 1364 1365 if(eventfd_write(m_poll_efd, 1)) { 1366 DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno); 1367 async_thread_force_stop = true; 1368 } 1369 1370 if (async_thread_created) 1371 pthread_join(m_tid,NULL); 1372 1373 DEBUG_PRINT_HIGH("venc_close X"); 1374 unsubscribe_to_events(m_nDriver_fd); 1375 close(m_poll_efd); 1376 close(m_nDriver_fd); 1377 m_nDriver_fd = -1; 1378 } 1379 1380 if (m_debug.infile) { 1381 fclose(m_debug.infile); 1382 m_debug.infile = NULL; 1383 } 1384 1385 if (m_debug.outfile) { 1386 fclose(m_debug.outfile); 1387 m_debug.outfile = NULL; 1388 } 1389 1390 if (m_debug.extradatafile) { 1391 fclose(m_debug.extradatafile); 1392 m_debug.extradatafile = NULL; 1393 } 1394 1395 if (m_debug.roiqpfile) { 1396 fclose(m_debug.roiqpfile); 1397 m_debug.roiqpfile = NULL; 1398 } 1399 } 1400 1401 bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count, 1402 OMX_U32 *actual_buff_count, 1403 OMX_U32 *buff_size, 1404 OMX_U32 port) 1405 { 1406 (void)min_buff_count, (void)buff_size; 1407 unsigned long temp_count = 0; 1408 1409 if (port == 0) { 1410 if (*actual_buff_count > m_sInput_buff_property.mincount) { 1411 temp_count = m_sInput_buff_property.actualcount; 1412 m_sInput_buff_property.actualcount = *actual_buff_count; 1413 DEBUG_PRINT_LOW("I/P Count set to %u", (unsigned int)*actual_buff_count); 1414 } 1415 } else { 1416 if (*actual_buff_count > m_sOutput_buff_property.mincount) { 1417 temp_count = m_sOutput_buff_property.actualcount; 1418 m_sOutput_buff_property.actualcount = *actual_buff_count; 1419 DEBUG_PRINT_LOW("O/P Count set to %u", (unsigned int)*actual_buff_count); 1420 } 1421 } 1422 1423 return true; 1424 1425 } 1426 1427 bool venc_dev::venc_loaded_start() 1428 { 1429 return true; 1430 } 1431 1432 bool venc_dev::venc_loaded_stop() 1433 { 1434 return true; 1435 } 1436 1437 bool venc_dev::venc_loaded_start_done() 1438 { 1439 return true; 1440 } 1441 1442 bool venc_dev::venc_loaded_stop_done() 1443 { 1444 return true; 1445 } 1446 1447 bool venc_dev::venc_get_seq_hdr(void *buffer, 1448 unsigned buffer_size, unsigned *header_len) 1449 { 1450 (void) buffer, (void) buffer_size, (void) header_len; 1451 return true; 1452 } 1453 1454 bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count, 1455 OMX_U32 *actual_buff_count, 1456 OMX_U32 *buff_size, 1457 OMX_U32 port) 1458 { 1459 struct v4l2_format fmt; 1460 struct v4l2_requestbuffers bufreq; 1461 unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; 1462 int ret; 1463 int extra_idx = 0; 1464 1465 if (port == 0) { 1466 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1467 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 1468 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 1469 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 1470 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; 1471 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 1472 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1473 bufreq.memory = V4L2_MEMORY_USERPTR; 1474 1475 if (*actual_buff_count) 1476 bufreq.count = *actual_buff_count; 1477 else 1478 bufreq.count = 2; 1479 1480 // Increase buffer-header count for metadata-mode on input port 1481 // to improve buffering and reduce bottlenecks in clients 1482 if (metadatamode && (bufreq.count < 9)) { 1483 DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9", 1484 bufreq.count); 1485 bufreq.count = 9; 1486 } 1487 if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) { 1488 DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count); 1489 bufreq.count = 11; 1490 } 1491 1492 int actualCount = bufreq.count; 1493 // Request MAX_V4L2_BUFS from V4L2 in batch mode. 1494 // Keep the original count for the client 1495 if (metadatamode && mBatchSize) { 1496 bufreq.count = MAX_V4L2_BUFS; 1497 } 1498 1499 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1500 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 1501 1502 if (ret) { 1503 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed"); 1504 return false; 1505 } 1506 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1507 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 1508 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 1509 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 1510 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 1511 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1512 1513 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = actualCount; 1514 *min_buff_count = m_sInput_buff_property.mincount; 1515 *actual_buff_count = m_sInput_buff_property.actualcount; 1516 #ifdef USE_ION 1517 // For ION memory allocations of the allocated buffer size 1518 // must be 4k aligned, hence aligning the input buffer 1519 // size to 4k. 1520 m_sInput_buff_property.datasize = ALIGN(m_sInput_buff_property.datasize, SZ_4K); 1521 #endif 1522 *buff_size = m_sInput_buff_property.datasize; 1523 num_input_planes = fmt.fmt.pix_mp.num_planes; 1524 extra_idx = EXTRADATA_IDX(num_input_planes); 1525 1526 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 1527 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 1528 } else if (extra_idx >= VIDEO_MAX_PLANES) { 1529 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); 1530 return OMX_ErrorBadParameter; 1531 } 1532 mInputExtradata.update(m_sInput_buff_property.actualcount + 1, extra_data_size); 1533 } else { 1534 unsigned int extra_idx = 0; 1535 memset(&fmt, 0, sizeof(fmt)); 1536 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1537 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1538 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1539 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1540 1541 ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); 1542 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1543 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1544 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1545 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1546 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1547 1548 ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); 1549 m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1550 bufreq.memory = V4L2_MEMORY_USERPTR; 1551 1552 if (mBatchSize) { 1553 // If we're in batch mode, we'd like to end up in a situation where 1554 // driver is able to own mBatchSize buffers and we'd also own atleast 1555 // mBatchSize buffers 1556 bufreq.count = MAX(*actual_buff_count, mBatchSize) + mBatchSize; 1557 } else if (*actual_buff_count) { 1558 bufreq.count = *actual_buff_count; 1559 } else { 1560 bufreq.count = 2; 1561 } 1562 1563 bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1564 ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); 1565 1566 if (ret) { 1567 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS CAPTURE_MPLANE Failed"); 1568 return false; 1569 } 1570 1571 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 1572 *min_buff_count = m_sOutput_buff_property.mincount; 1573 *actual_buff_count = m_sOutput_buff_property.actualcount; 1574 *buff_size = m_sOutput_buff_property.datasize; 1575 num_output_planes = fmt.fmt.pix_mp.num_planes; 1576 extra_idx = EXTRADATA_IDX(num_output_planes); 1577 1578 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 1579 extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; 1580 } else if (extra_idx >= VIDEO_MAX_PLANES) { 1581 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 1582 return OMX_ErrorBadParameter; 1583 } 1584 mOutputExtradata.update(m_sOutput_buff_property.actualcount, extra_data_size); 1585 } 1586 1587 return true; 1588 } 1589 1590 bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index) 1591 { 1592 DEBUG_PRINT_LOW("venc_set_param:: venc-720p"); 1593 struct v4l2_format fmt; 1594 struct v4l2_requestbuffers bufreq; 1595 int ret; 1596 1597 switch ((int)index) { 1598 case OMX_IndexParamPortDefinition: 1599 { 1600 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 1601 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 1602 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition"); 1603 1604 if (portDefn->nPortIndex == PORT_INDEX_IN) { 1605 if (!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) { 1606 return false; 1607 } 1608 1609 if (!venc_set_color_format(portDefn->format.video.eColorFormat)) { 1610 return false; 1611 } 1612 if (enable_mv_narrow_searchrange && 1613 (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >= 1614 (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) { 1615 if (venc_set_searchrange() == false) { 1616 DEBUG_PRINT_ERROR("ERROR: Failed to set search range"); 1617 } 1618 } 1619 if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight || 1620 m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) { 1621 DEBUG_PRINT_LOW("Basic parameter has changed"); 1622 m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; 1623 m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; 1624 1625 memset(&fmt, 0, sizeof(fmt)); 1626 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1627 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 1628 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 1629 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 1630 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; 1631 1632 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 1633 DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed"); 1634 hw_overload = errno == EBUSY; 1635 return false; 1636 } 1637 1638 m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1639 bufreq.memory = V4L2_MEMORY_USERPTR; 1640 bufreq.count = portDefn->nBufferCountActual; 1641 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1642 1643 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 1644 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed"); 1645 return false; 1646 } 1647 1648 if (bufreq.count == portDefn->nBufferCountActual) 1649 m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; 1650 1651 if (portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) 1652 m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; 1653 } 1654 1655 DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u", 1656 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count); 1657 } else if (portDefn->nPortIndex == PORT_INDEX_OUT) { 1658 m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight; 1659 m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth; 1660 1661 memset(&fmt, 0, sizeof(fmt)); 1662 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1663 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 1664 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 1665 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 1666 1667 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 1668 DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed"); 1669 hw_overload = errno == EBUSY; 1670 return false; 1671 } 1672 1673 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 1674 1675 if (!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) { 1676 return false; 1677 } 1678 1679 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 1680 bufreq.memory = V4L2_MEMORY_USERPTR; 1681 bufreq.count = portDefn->nBufferCountActual; 1682 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1683 1684 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 1685 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u", 1686 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.actualcount); 1687 return false; 1688 } 1689 1690 if (bufreq.count == portDefn->nBufferCountActual) 1691 m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; 1692 1693 if (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) 1694 m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; 1695 1696 DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u", 1697 (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count); 1698 } else { 1699 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); 1700 } 1701 1702 break; 1703 } 1704 case OMX_IndexParamVideoPortFormat: 1705 { 1706 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; 1707 portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 1708 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat"); 1709 1710 if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) { 1711 if (!venc_set_color_format(portFmt->eColorFormat)) { 1712 return false; 1713 } 1714 } else if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1715 if (!venc_set_encode_framerate(portFmt->xFramerate, 0)) { 1716 return false; 1717 } 1718 } else { 1719 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); 1720 } 1721 1722 break; 1723 } 1724 case OMX_IndexParamVideoBitrate: 1725 { 1726 OMX_VIDEO_PARAM_BITRATETYPE* pParam; 1727 pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 1728 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate"); 1729 1730 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1731 if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) { 1732 DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed"); 1733 return false; 1734 } 1735 1736 if (!venc_set_ratectrl_cfg(pParam->eControlRate)) { 1737 DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed"); 1738 return false; 1739 } 1740 } else { 1741 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); 1742 } 1743 1744 break; 1745 } 1746 case OMX_IndexParamVideoMpeg4: 1747 { 1748 OMX_VIDEO_PARAM_MPEG4TYPE* pParam; 1749 OMX_U32 bFrames = 0; 1750 1751 pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 1752 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4"); 1753 1754 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1755 if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) { 1756 DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed"); 1757 return false; 1758 } 1759 1760 m_profile_set = false; 1761 m_level_set = false; 1762 rc_off_level = (int)pParam->eLevel; 1763 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1764 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level"); 1765 return false; 1766 } else { 1767 if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 1768 if (pParam->nBFrames) { 1769 bFrames = pParam->nBFrames; 1770 } 1771 } else { 1772 if (pParam->nBFrames) { 1773 DEBUG_PRINT_ERROR("Warning: B frames not supported"); 1774 bFrames = 0; 1775 } 1776 } 1777 } 1778 1779 if (!venc_set_intra_period_config (pParam->nPFrames,bFrames)) { 1780 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1781 return false; 1782 } 1783 1784 if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) { 1785 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config"); 1786 return false; 1787 } 1788 } else { 1789 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); 1790 } 1791 1792 break; 1793 } 1794 case OMX_IndexParamVideoH263: 1795 { 1796 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 1797 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263"); 1798 OMX_U32 bFrames = 0; 1799 1800 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1801 m_profile_set = false; 1802 m_level_set = false; 1803 rc_off_level = (int)pParam->eLevel; 1804 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1805 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level"); 1806 return false; 1807 } 1808 1809 if (pParam->nBFrames) 1810 DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263"); 1811 1812 if (venc_set_intra_period_config (pParam->nPFrames, bFrames) == false) { 1813 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1814 return false; 1815 } 1816 } else { 1817 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263"); 1818 } 1819 1820 break; 1821 } 1822 case OMX_IndexParamVideoAvc: 1823 { 1824 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc"); 1825 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 1826 OMX_U32 bFrames = 0; 1827 1828 if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1829 DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d", 1830 pParam->eProfile,pParam->eLevel); 1831 1832 m_profile_set = false; 1833 m_level_set = false; 1834 rc_off_level = (int)pParam->eLevel; 1835 if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) { 1836 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d", 1837 pParam->eProfile, pParam->eLevel); 1838 return false; 1839 } else { 1840 if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) && 1841 (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) { 1842 if (pParam->nBFrames) { 1843 bFrames = pParam->nBFrames; 1844 } 1845 } else { 1846 if (pParam->nBFrames) { 1847 DEBUG_PRINT_ERROR("Warning: B frames not supported"); 1848 bFrames = 0; 1849 } 1850 } 1851 } 1852 1853 if (!venc_set_intra_period_config (pParam->nPFrames, bFrames)) { 1854 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1855 return false; 1856 } 1857 1858 if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) { 1859 DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed"); 1860 return false; 1861 } 1862 1863 if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) { 1864 DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed"); 1865 return false; 1866 } 1867 1868 if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) { 1869 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config"); 1870 return false; 1871 } 1872 } else { 1873 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); 1874 } 1875 1876 //TBD, lot of other variables to be updated, yet to decide 1877 break; 1878 } 1879 case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8: 1880 { 1881 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8"); 1882 OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData; 1883 rc_off_level = (int)pParam->eLevel; 1884 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1885 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d", 1886 pParam->eProfile, pParam->eLevel); 1887 return false; 1888 } 1889 if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) { 1890 DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience"); 1891 return false; 1892 } 1893 if(!venc_set_ltrmode(1, 1)) { 1894 DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode"); 1895 return false; 1896 } 1897 1898 // For VP8, hier-p and ltr are mutually exclusive features in firmware 1899 // Disable hier-p if ltr is enabled. 1900 if (m_codec == OMX_VIDEO_CodingVP8) { 1901 DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set"); 1902 if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) { 1903 DEBUG_PRINT_ERROR("Disabling Hier P count failed"); 1904 } 1905 } 1906 1907 break; 1908 } 1909 case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc: 1910 { 1911 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc"); 1912 OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData; 1913 rc_off_level = (int)pParam->eLevel; 1914 if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) { 1915 DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d", 1916 pParam->eProfile, pParam->eLevel); 1917 return false; 1918 } 1919 if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable)) 1920 DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder"); 1921 1922 OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30; 1923 OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1; 1924 if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) { 1925 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 1926 return false; 1927 } 1928 break; 1929 } 1930 case OMX_IndexParamVideoIntraRefresh: 1931 { 1932 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh"); 1933 OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = 1934 (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; 1935 1936 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1937 if (venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) { 1938 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 1939 return false; 1940 } 1941 } else { 1942 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); 1943 } 1944 1945 break; 1946 } 1947 case OMX_IndexParamVideoErrorCorrection: 1948 { 1949 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection"); 1950 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = 1951 (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; 1952 1953 if (error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1954 if (venc_set_error_resilience(error_resilience) == false) { 1955 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 1956 return false; 1957 } 1958 } else { 1959 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); 1960 } 1961 1962 break; 1963 } 1964 case OMX_IndexParamVideoProfileLevelCurrent: 1965 { 1966 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent"); 1967 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = 1968 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; 1969 1970 if (profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1971 m_profile_set = false; 1972 m_level_set = false; 1973 rc_off_level = (int)profile_level->eLevel; 1974 if (!venc_set_profile_level (profile_level->eProfile, 1975 profile_level->eLevel)) { 1976 DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level"); 1977 return false; 1978 } 1979 } else { 1980 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); 1981 } 1982 1983 break; 1984 } 1985 case OMX_IndexParamVideoQuantization: 1986 { 1987 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization"); 1988 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = 1989 (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; 1990 if (session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 1991 if (venc_set_session_qp (session_qp->nQpI, 1992 session_qp->nQpP, 1993 session_qp->nQpB) == false) { 1994 DEBUG_PRINT_ERROR("ERROR: Setting Session QP failed"); 1995 return false; 1996 } 1997 } else { 1998 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); 1999 } 2000 2001 break; 2002 } 2003 case QOMX_IndexParamVideoInitialQp: 2004 { 2005 QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp = 2006 (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData; 2007 if (initqp->bEnableInitQp) { 2008 DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp); 2009 if(venc_enable_initial_qp(initqp) == false) { 2010 DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP"); 2011 return OMX_ErrorUnsupportedSetting; 2012 } 2013 } else 2014 DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp"); 2015 break; 2016 } 2017 case OMX_QcomIndexParamVideoQPRange: 2018 { 2019 DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange"); 2020 OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range = 2021 (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData; 2022 2023 if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 2024 if(venc_set_session_qp_range (session_qp_range->minQP, 2025 session_qp_range->maxQP) == false) { 2026 DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed", 2027 (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP); 2028 return false; 2029 } else { 2030 session_qp_values.minqp = session_qp_range->minQP; 2031 session_qp_values.maxqp = session_qp_range->maxQP; 2032 } 2033 } else { 2034 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange"); 2035 } 2036 2037 break; 2038 } 2039 case OMX_QcomIndexEnableSliceDeliveryMode: 2040 { 2041 QOMX_EXTNINDEX_PARAMTYPE* pParam = 2042 (QOMX_EXTNINDEX_PARAMTYPE*)paramData; 2043 2044 if (pParam->nPortIndex == PORT_INDEX_OUT) { 2045 if (venc_set_slice_delivery_mode(pParam->bEnable) == false) { 2046 DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); 2047 return OMX_ErrorUnsupportedSetting; 2048 } 2049 } else { 2050 DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " 2051 "called on wrong port(%u)", (unsigned int)pParam->nPortIndex); 2052 return OMX_ErrorBadPortIndex; 2053 } 2054 2055 break; 2056 } 2057 case OMX_ExtraDataFrameDimension: 2058 { 2059 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension"); 2060 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData); 2061 2062 if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) { 2063 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed"); 2064 return false; 2065 } 2066 2067 extradata = true; 2068 break; 2069 } 2070 case OMX_ExtraDataVideoEncoderSliceInfo: 2071 { 2072 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); 2073 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData); 2074 2075 if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) { 2076 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed"); 2077 return false; 2078 } 2079 2080 extradata = true; 2081 break; 2082 } 2083 case OMX_ExtraDataVideoEncoderMBInfo: 2084 { 2085 DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo"); 2086 OMX_BOOL extra_data = *(OMX_BOOL *)(paramData); 2087 2088 if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) { 2089 DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed"); 2090 return false; 2091 } 2092 2093 extradata = true; 2094 break; 2095 } 2096 case OMX_QcomIndexParamSequenceHeaderWithIDR: 2097 { 2098 PrependSPSPPSToIDRFramesParams * pParam = 2099 (PrependSPSPPSToIDRFramesParams *)paramData; 2100 2101 DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable); 2102 if(venc_set_inband_video_header(pParam->bEnable) == false) { 2103 DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed"); 2104 return OMX_ErrorUnsupportedSetting; 2105 } 2106 2107 break; 2108 } 2109 case OMX_QcomIndexParamH264AUDelimiter: 2110 { 2111 OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam = 2112 (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData; 2113 2114 DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable); 2115 if(venc_set_au_delimiter(pParam->bEnable) == false) { 2116 DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed"); 2117 return OMX_ErrorUnsupportedSetting; 2118 } 2119 2120 break; 2121 } 2122 case OMX_QcomIndexParamMBIStatisticsMode: 2123 { 2124 OMX_QOMX_VIDEO_MBI_STATISTICS * pParam = 2125 (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData; 2126 2127 DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType); 2128 if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) { 2129 DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed"); 2130 return OMX_ErrorUnsupportedSetting; 2131 } 2132 2133 break; 2134 } 2135 2136 case OMX_QcomIndexConfigH264EntropyCodingCabac: 2137 { 2138 QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam = 2139 (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData; 2140 2141 DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac); 2142 if(venc_set_entropy_config (pParam->bCabac, 0) == false) { 2143 DEBUG_PRINT_ERROR("ERROR: set Entropy failed"); 2144 return OMX_ErrorUnsupportedSetting; 2145 } 2146 2147 break; 2148 } 2149 2150 case OMX_QcomIndexHierarchicalStructure: 2151 { 2152 QOMX_VIDEO_HIERARCHICALLAYERS* pParam = 2153 (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData; 2154 2155 if (pParam->nPortIndex == PORT_INDEX_OUT) { 2156 if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) { 2157 DEBUG_PRINT_ERROR("Setting Hier P count failed"); 2158 return false; 2159 } 2160 } else { 2161 DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex); 2162 return false; 2163 } 2164 2165 // For VP8, hier-p and ltr are mutually exclusive features in firmware 2166 // Disable ltr if hier-p is enabled. 2167 if (m_codec == OMX_VIDEO_CodingVP8) { 2168 DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set"); 2169 if(!venc_set_ltrmode(0, 1)) { 2170 DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode"); 2171 } 2172 } 2173 break; 2174 } 2175 case OMX_QcomIndexParamPerfLevel: 2176 { 2177 OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam = 2178 (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData; 2179 DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel); 2180 if (!venc_set_perf_level(pParam->ePerfLevel)) { 2181 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel); 2182 return false; 2183 } else { 2184 performance_level.perflevel = (unsigned int) pParam->ePerfLevel; 2185 } 2186 break; 2187 } 2188 case OMX_QcomIndexParamH264VUITimingInfo: 2189 { 2190 OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam = 2191 (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData; 2192 DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable); 2193 if(venc_set_vui_timing_info(pParam->bEnable) == false) { 2194 DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable); 2195 return false; 2196 } else { 2197 vui_timing_info.enabled = (unsigned int) pParam->bEnable; 2198 } 2199 break; 2200 } 2201 case OMX_QTIIndexParamVQZIPSEIType: 2202 { 2203 OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam = 2204 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData; 2205 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable); 2206 if(venc_set_vqzip_sei_type(pParam->bEnable) == false) { 2207 DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable); 2208 return false; 2209 } 2210 break; 2211 } 2212 case OMX_QcomIndexParamPeakBitrate: 2213 { 2214 OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam = 2215 (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData; 2216 DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate); 2217 if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) { 2218 DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate); 2219 return false; 2220 } else { 2221 peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate; 2222 } 2223 break; 2224 } 2225 case OMX_QcomIndexParamSetMVSearchrange: 2226 { 2227 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange"); 2228 is_searchrange_set = true; 2229 if (!venc_set_searchrange()) { 2230 DEBUG_PRINT_ERROR("ERROR: Failed to set search range"); 2231 return false; 2232 } 2233 } 2234 break; 2235 case OMX_QcomIndexParamVideoLTRCount: 2236 { 2237 DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount"); 2238 OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam = 2239 (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData; 2240 if (pParam->nCount > 0) { 2241 if (venc_set_ltrmode(1, pParam->nCount) == false) { 2242 DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed"); 2243 return false; 2244 } 2245 } else { 2246 if (venc_set_ltrmode(0, 0) == false) { 2247 DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed"); 2248 return false; 2249 } 2250 } 2251 break; 2252 } 2253 case OMX_QcomIndexParamVideoHybridHierpMode: 2254 { 2255 if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) { 2256 DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed"); 2257 return false; 2258 } 2259 break; 2260 } 2261 case OMX_QcomIndexParamBatchSize: 2262 { 2263 OMX_PARAM_U32TYPE* pParam = 2264 (OMX_PARAM_U32TYPE*)paramData; 2265 2266 if (pParam->nPortIndex == PORT_INDEX_OUT) { 2267 DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported" 2268 " on output port"); 2269 return OMX_ErrorUnsupportedSetting; 2270 } 2271 2272 if (!venc_set_batch_size(pParam->nU32)) { 2273 DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32); 2274 return OMX_ErrorUnsupportedSetting; 2275 } 2276 break; 2277 } 2278 case OMX_QcomIndexParamVencAspectRatio: 2279 { 2280 if (!venc_set_aspectratio(paramData)) { 2281 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed"); 2282 return OMX_ErrorUnsupportedSetting; 2283 } 2284 break; 2285 } 2286 case OMX_QTIIndexParamVideoEnableRoiInfo: 2287 { 2288 struct v4l2_control control; 2289 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 && 2290 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) { 2291 DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype); 2292 return OMX_ErrorUnsupportedSetting; 2293 } 2294 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 2295 control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP; 2296 DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo"); 2297 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 2298 DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed"); 2299 return OMX_ErrorUnsupportedSetting; 2300 } 2301 break; 2302 } 2303 case OMX_IndexParamAndroidVideoTemporalLayering: 2304 { 2305 if (venc_set_temporal_layers( 2306 (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) { 2307 DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers"); 2308 return false; 2309 } 2310 break; 2311 } 2312 case OMX_IndexParamVideoSliceFMO: 2313 default: 2314 DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u", 2315 index); 2316 break; 2317 //case 2318 } 2319 2320 return true; 2321 } 2322 2323 bool venc_dev::venc_check_valid_config() 2324 { 2325 if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] && 2326 ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) || 2327 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) { 2328 DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases"); 2329 DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled"); 2330 DEBUG_PRINT_ERROR("For H265 : When Hier P enabled"); 2331 return false; 2332 } 2333 return true; 2334 } 2335 2336 bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) 2337 { 2338 2339 DEBUG_PRINT_LOW("Inside venc_set_config"); 2340 2341 if(!venc_check_valid_config()) { 2342 DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration"); 2343 return false; 2344 } 2345 2346 switch ((int)index) { 2347 case OMX_IndexConfigVideoBitrate: 2348 { 2349 OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) 2350 configData; 2351 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoBitrate"); 2352 2353 if (bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 2354 if (venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) { 2355 DEBUG_PRINT_ERROR("ERROR: Setting Target Bit rate failed"); 2356 return false; 2357 } 2358 } else { 2359 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); 2360 } 2361 2362 break; 2363 } 2364 case OMX_IndexConfigVideoFramerate: 2365 { 2366 OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) 2367 configData; 2368 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoFramerate"); 2369 2370 if (frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 2371 if (venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) { 2372 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed"); 2373 return false; 2374 } 2375 } else { 2376 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 2377 } 2378 2379 break; 2380 } 2381 case QOMX_IndexConfigVideoIntraperiod: 2382 { 2383 DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod"); 2384 QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = 2385 (QOMX_VIDEO_INTRAPERIODTYPE *)configData; 2386 2387 if (intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 2388 if (venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) { 2389 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 2390 return false; 2391 } 2392 } 2393 2394 break; 2395 } 2396 case OMX_IndexConfigVideoIntraVOPRefresh: 2397 { 2398 OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) 2399 configData; 2400 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); 2401 2402 if (intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 2403 if (venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) { 2404 DEBUG_PRINT_ERROR("ERROR: Setting Encode Framerate failed"); 2405 return false; 2406 } 2407 } else { 2408 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); 2409 } 2410 2411 break; 2412 } 2413 case OMX_IndexConfigCommonRotate: 2414 { 2415 OMX_CONFIG_ROTATIONTYPE *config_rotation = 2416 reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 2417 OMX_U32 nFrameWidth; 2418 if (!config_rotation) { 2419 return false; 2420 } 2421 if (true == deinterlace_enabled) { 2422 DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing"); 2423 return false; 2424 } 2425 DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims"); 2426 nFrameWidth = m_sVenc_cfg.dvs_width; 2427 m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height; 2428 m_sVenc_cfg.dvs_height = nFrameWidth; 2429 2430 if(venc_set_vpe_rotation(config_rotation->nRotation) == false) { 2431 DEBUG_PRINT_ERROR("ERROR: Dimension Change for Rotation failed"); 2432 return false; 2433 } 2434 2435 break; 2436 } 2437 case OMX_IndexConfigVideoAVCIntraPeriod: 2438 { 2439 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; 2440 DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod"); 2441 2442 if (venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod) 2443 == false) { 2444 DEBUG_PRINT_ERROR("ERROR: Setting " 2445 "OMX_IndexConfigVideoAVCIntraPeriod failed"); 2446 return false; 2447 } 2448 break; 2449 } 2450 case OMX_IndexConfigCommonDeinterlace: 2451 { 2452 OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData; 2453 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace"); 2454 if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) { 2455 if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height && 2456 m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width) 2457 { 2458 DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation"); 2459 return false; 2460 } 2461 if(venc_set_deinterlace(deinterlace->nEnable) == false) { 2462 DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed"); 2463 return false; 2464 } 2465 } else { 2466 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace"); 2467 } 2468 break; 2469 } 2470 case OMX_IndexConfigVideoVp8ReferenceFrame: 2471 { 2472 OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData; 2473 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame"); 2474 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) && 2475 (vp8refframe->bUseGoldenFrame)) { 2476 if(venc_set_useltr(0x1) == false) { 2477 DEBUG_PRINT_ERROR("ERROR: use goldenframe failed"); 2478 return false; 2479 } 2480 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) && 2481 (vp8refframe->bGoldenFrameRefresh)) { 2482 if(venc_set_markltr(0x1) == false) { 2483 DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed"); 2484 return false; 2485 } 2486 } else { 2487 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame"); 2488 } 2489 break; 2490 } 2491 case OMX_QcomIndexConfigVideoLTRUse: 2492 { 2493 OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData; 2494 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse"); 2495 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) { 2496 if (venc_set_useltr(pParam->nID) == false) { 2497 DEBUG_PRINT_ERROR("ERROR: Use LTR failed"); 2498 return false; 2499 } 2500 } else { 2501 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse"); 2502 } 2503 break; 2504 } 2505 case OMX_QcomIndexConfigVideoLTRMark: 2506 { 2507 OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData; 2508 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark"); 2509 if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) { 2510 if (venc_set_markltr(pParam->nID) == false) { 2511 DEBUG_PRINT_ERROR("ERROR: Mark LTR failed"); 2512 return false; 2513 } 2514 } else { 2515 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark"); 2516 } 2517 break; 2518 } 2519 case OMX_QcomIndexConfigPerfLevel: 2520 { 2521 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf = 2522 (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData; 2523 DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel); 2524 if (!venc_set_perf_level(perf->ePerfLevel)) { 2525 DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel); 2526 return false; 2527 } else { 2528 performance_level.perflevel = (unsigned int) perf->ePerfLevel; 2529 } 2530 break; 2531 } 2532 case OMX_QcomIndexConfigVideoVencPerfMode: 2533 { 2534 QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData; 2535 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode"); 2536 if (venc_set_perf_mode(pParam->nPerfMode) == false) { 2537 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE"); 2538 return false; 2539 } 2540 break; 2541 } 2542 case OMX_QcomIndexConfigNumHierPLayers: 2543 { 2544 QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam = 2545 (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData; 2546 DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers"); 2547 if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) { 2548 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers"); 2549 return false; 2550 } 2551 break; 2552 } 2553 case OMX_QcomIndexConfigBaseLayerId: 2554 { 2555 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam = 2556 (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData; 2557 if (venc_set_baselayerid(pParam->nPID) == false) { 2558 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed"); 2559 return OMX_ErrorUnsupportedSetting; 2560 } 2561 break; 2562 } 2563 case OMX_IndexParamAndroidVideoTemporalLayering: 2564 { 2565 DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!"); 2566 return false; 2567 } 2568 case OMX_QcomIndexConfigQp: 2569 { 2570 OMX_SKYPE_VIDEO_CONFIG_QP* pParam = 2571 (OMX_SKYPE_VIDEO_CONFIG_QP*) configData; 2572 if (venc_set_qp(pParam->nQP) == false) { 2573 DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed"); 2574 return OMX_ErrorUnsupportedSetting; 2575 } 2576 break; 2577 } 2578 case OMX_IndexConfigPriority: 2579 { 2580 OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData; 2581 DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32); 2582 if (!venc_set_priority(priority->nU32)) { 2583 DEBUG_PRINT_ERROR("Failed to set priority"); 2584 return false; 2585 } 2586 sess_priority.priority = priority->nU32; 2587 break; 2588 } 2589 case OMX_IndexConfigOperatingRate: 2590 { 2591 OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData; 2592 DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32); 2593 if (!venc_set_operatingrate(rate->nU32)) { 2594 DEBUG_PRINT_ERROR("Failed to set operating rate"); 2595 return false; 2596 } 2597 break; 2598 } 2599 case OMX_QTIIndexConfigVideoRoiInfo: 2600 { 2601 if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) { 2602 DEBUG_PRINT_ERROR("Failed to set ROI QP info"); 2603 return false; 2604 } 2605 break; 2606 } 2607 case OMX_IndexConfigAndroidIntraRefresh: 2608 { 2609 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData; 2610 DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod); 2611 2612 if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) { 2613 OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, 16)/16) * (ALIGN(m_sVenc_cfg.dvs_width, 16)/16); 2614 OMX_U32 num_intra_refresh_mbs = num_mbs_per_frame / intra_refresh->nRefreshPeriod; 2615 2616 if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) { 2617 DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed"); 2618 return false; 2619 } 2620 } else { 2621 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType"); 2622 } 2623 break; 2624 } 2625 case OMX_QTIIndexConfigDescribeColorAspects: 2626 { 2627 DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData; 2628 2629 OMX_U32 color_space = MSM_VIDC_BT601_6_625; 2630 OMX_U32 full_range = 0; 2631 OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625; 2632 OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625; 2633 2634 switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) { 2635 case ColorAspects::PrimariesBT709_5: 2636 color_space = MSM_VIDC_BT709_5; 2637 break; 2638 case ColorAspects::PrimariesBT470_6M: 2639 color_space = MSM_VIDC_BT470_6_M; 2640 break; 2641 case ColorAspects::PrimariesBT601_6_625: 2642 color_space = MSM_VIDC_BT601_6_625; 2643 break; 2644 case ColorAspects::PrimariesBT601_6_525: 2645 color_space = MSM_VIDC_BT601_6_525; 2646 break; 2647 case ColorAspects::PrimariesGenericFilm: 2648 color_space = MSM_VIDC_GENERIC_FILM; 2649 break; 2650 case ColorAspects::PrimariesBT2020: 2651 color_space = MSM_VIDC_BT2020; 2652 break; 2653 default: 2654 color_space = MSM_VIDC_BT601_6_625; 2655 //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625; 2656 break; 2657 } 2658 switch((ColorAspects::Range)params->sAspects.mRange) { 2659 case ColorAspects::RangeFull: 2660 full_range = 1; 2661 break; 2662 case ColorAspects::RangeLimited: 2663 full_range = 0; 2664 break; 2665 default: 2666 break; 2667 } 2668 switch((ColorAspects::Transfer)params->sAspects.mTransfer) { 2669 case ColorAspects::TransferSMPTE170M: 2670 transfer_chars = MSM_VIDC_TRANSFER_601_6_525; 2671 break; 2672 case ColorAspects::TransferUnspecified: 2673 transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED; 2674 break; 2675 case ColorAspects::TransferGamma22: 2676 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M; 2677 break; 2678 case ColorAspects::TransferGamma28: 2679 transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG; 2680 break; 2681 case ColorAspects::TransferSMPTE240M: 2682 transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M; 2683 break; 2684 case ColorAspects::TransferLinear: 2685 transfer_chars = MSM_VIDC_TRANSFER_LINEAR; 2686 break; 2687 case ColorAspects::TransferXvYCC: 2688 transfer_chars = MSM_VIDC_TRANSFER_IEC_61966; 2689 break; 2690 case ColorAspects::TransferBT1361: 2691 transfer_chars = MSM_VIDC_TRANSFER_BT_1361; 2692 break; 2693 case ColorAspects::TransferSRGB: 2694 transfer_chars = MSM_VIDC_TRANSFER_SRGB; 2695 break; 2696 default: 2697 //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M; 2698 transfer_chars = MSM_VIDC_TRANSFER_601_6_625; 2699 break; 2700 } 2701 switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) { 2702 case ColorAspects::MatrixUnspecified: 2703 matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED; 2704 break; 2705 case ColorAspects::MatrixBT709_5: 2706 matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5; 2707 break; 2708 case ColorAspects::MatrixBT470_6M: 2709 matrix_coeffs = MSM_VIDC_MATRIX_FCC_47; 2710 break; 2711 case ColorAspects::MatrixBT601_6: 2712 matrix_coeffs = MSM_VIDC_MATRIX_601_6_525; 2713 break; 2714 case ColorAspects::MatrixSMPTE240M: 2715 transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M; 2716 break; 2717 case ColorAspects::MatrixBT2020: 2718 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020; 2719 break; 2720 case ColorAspects::MatrixBT2020Constant: 2721 matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST; 2722 break; 2723 default: 2724 //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6; 2725 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625; 2726 break; 2727 } 2728 if (!venc_set_colorspace(color_space, full_range, 2729 transfer_chars, matrix_coeffs)) { 2730 2731 DEBUG_PRINT_ERROR("Failed to set operating rate"); 2732 return false; 2733 } 2734 break; 2735 } 2736 default: 2737 DEBUG_PRINT_ERROR("Unsupported config index = %u", index); 2738 break; 2739 } 2740 2741 return true; 2742 } 2743 2744 unsigned venc_dev::venc_stop( void) 2745 { 2746 struct venc_msg venc_msg; 2747 struct v4l2_requestbuffers bufreq; 2748 int rc = 0, ret = 0; 2749 2750 if (!stopped) { 2751 enum v4l2_buf_type cap_type; 2752 2753 if (streaming[OUTPUT_PORT]) { 2754 cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2755 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); 2756 2757 if (rc) { 2758 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d", 2759 cap_type, rc); 2760 } else 2761 streaming[OUTPUT_PORT] = false; 2762 2763 DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port"); 2764 bufreq.memory = V4L2_MEMORY_USERPTR; 2765 bufreq.count = 0; 2766 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2767 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); 2768 2769 if (ret) { 2770 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed"); 2771 return false; 2772 } 2773 } 2774 2775 if (!rc && streaming[CAPTURE_PORT]) { 2776 cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2777 rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); 2778 2779 if (rc) { 2780 DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d", 2781 cap_type, rc); 2782 } else 2783 streaming[CAPTURE_PORT] = false; 2784 2785 DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port"); 2786 bufreq.memory = V4L2_MEMORY_USERPTR; 2787 bufreq.count = 0; 2788 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2789 ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq); 2790 2791 if (ret) { 2792 DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed"); 2793 return false; 2794 } 2795 } 2796 2797 if (!rc && !ret) { 2798 venc_stop_done(); 2799 stopped = 1; 2800 /*set flag to re-configure when started again*/ 2801 resume_in_stopped = 1; 2802 2803 } 2804 } 2805 2806 return rc; 2807 } 2808 2809 unsigned venc_dev::venc_pause(void) 2810 { 2811 pthread_mutex_lock(&pause_resume_mlock); 2812 paused = true; 2813 pthread_mutex_unlock(&pause_resume_mlock); 2814 return 0; 2815 } 2816 2817 unsigned venc_dev::venc_resume(void) 2818 { 2819 pthread_mutex_lock(&pause_resume_mlock); 2820 paused = false; 2821 pthread_mutex_unlock(&pause_resume_mlock); 2822 2823 return pthread_cond_signal(&pause_resume_cond); 2824 } 2825 2826 unsigned venc_dev::venc_start_done(void) 2827 { 2828 struct venc_msg venc_msg; 2829 venc_msg.msgcode = VEN_MSG_START; 2830 venc_msg.statuscode = VEN_S_SUCCESS; 2831 venc_handle->async_message_process(venc_handle,&venc_msg); 2832 return 0; 2833 } 2834 2835 unsigned venc_dev::venc_stop_done(void) 2836 { 2837 struct venc_msg venc_msg; 2838 venc_msg.msgcode=VEN_MSG_STOP; 2839 venc_msg.statuscode=VEN_S_SUCCESS; 2840 venc_handle->async_message_process(venc_handle,&venc_msg); 2841 return 0; 2842 } 2843 2844 unsigned venc_dev::venc_set_message_thread_id(pthread_t tid) 2845 { 2846 async_thread_created = true; 2847 m_tid=tid; 2848 return 0; 2849 } 2850 2851 bool venc_dev::venc_set_vqzip_defaults() 2852 { 2853 struct v4l2_control control; 2854 int rc = 0, num_mbs_per_frame; 2855 2856 num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width; 2857 2858 switch (num_mbs_per_frame) { 2859 case OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT: 2860 case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT: 2861 case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT: 2862 case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT: 2863 break; 2864 default: 2865 DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu", 2866 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height); 2867 return false; 2868 } 2869 2870 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL; 2871 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF; 2872 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2873 if (rc) 2874 DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP"); 2875 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 2876 control.value = INT_MAX; 2877 2878 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2879 if (rc) 2880 DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP"); 2881 2882 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; 2883 control.value = 0; 2884 2885 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2886 if (rc) 2887 DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP"); 2888 2889 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE; 2890 control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY; 2891 2892 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2893 if (rc) 2894 DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP"); 2895 2896 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 2897 control.value = 1; 2898 2899 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2900 if (rc) 2901 DEBUG_PRINT_ERROR("Failed to set IDR period for VQZIP"); 2902 2903 return true; 2904 } 2905 2906 2907 unsigned venc_dev::venc_start(void) 2908 { 2909 enum v4l2_buf_type buf_type; 2910 int ret, r; 2911 struct v4l2_control control; 2912 2913 memset(&control, 0, sizeof(control)); 2914 2915 DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start", 2916 __func__); 2917 m_level_set = false; 2918 2919 if (!venc_set_profile_level(0, 0)) { 2920 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET", 2921 __func__); 2922 } else { 2923 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET", 2924 __func__, codec_profile.profile, profile_level.level); 2925 } 2926 2927 if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults()) 2928 return 1; 2929 2930 // disable B-frames for realtime high-resolution/fps usecases for power considerations 2931 if (intra_period.num_bframes && 2932 sess_priority.priority == 0 /*realtime*/ && 2933 (((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) > (1920 * 1088)) || 2934 (operating_rate >= 60 << 16))) { 2935 intra_period.num_pframes += (intra_period.num_bframes + 1); 2936 intra_period.num_bframes = 0; 2937 if (venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) { 2938 DEBUG_PRINT_INFO("Disabling B frames: res = %lux%lu : operating-rate = %u frames/sec", 2939 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, operating_rate >> 16); 2940 } else { 2941 DEBUG_PRINT_ERROR("Failed to disable B frames!"); 2942 } 2943 } 2944 2945 // re-configure the temporal layers as RC-mode and key-frame interval 2946 // might have changed since the client last configured the layers. 2947 if (temporal_layers_config.nPLayers) { 2948 if (venc_set_temporal_layers_internal() != OMX_ErrorNone) { 2949 DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !"); 2950 } else { 2951 // request buffers on capture port again since internal (scratch)- 2952 // buffer requirements may change (i.e if we switch from non-hybrid 2953 // to hybrid mode and vice-versa) 2954 struct v4l2_requestbuffers bufreq; 2955 2956 bufreq.memory = V4L2_MEMORY_USERPTR; 2957 bufreq.count = m_sOutput_buff_property.actualcount; 2958 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2959 if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) { 2960 DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers"); 2961 } 2962 } 2963 } 2964 2965 venc_config_print(); 2966 2967 if(resume_in_stopped){ 2968 /*set buffercount when restarted*/ 2969 venc_reconfig_reqbufs(); 2970 resume_in_stopped = 0; 2971 } 2972 2973 /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */ 2974 if (slice_mode.enable && multislice.mslice_size && 2975 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) { 2976 DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable, 2977 (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size), 2978 MAX_SUPPORTED_SLICES_PER_FRAME); 2979 return 1; 2980 } 2981 2982 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2983 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing"); 2984 ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type); 2985 2986 if (ret) 2987 return 1; 2988 2989 streaming[CAPTURE_PORT] = true; 2990 2991 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER; 2992 control.value = 1; 2993 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 2994 if (ret) { 2995 DEBUG_PRINT_ERROR("failed to request seq header"); 2996 return 1; 2997 } 2998 2999 3000 stopped = 0; 3001 return 0; 3002 } 3003 3004 inline const char* hiermode_string(int val) 3005 { 3006 switch(val) 3007 { 3008 case HIER_NONE: 3009 return "No Hier"; 3010 case HIER_P: 3011 return "Hier-P"; 3012 case HIER_B: 3013 return "Hier-B"; 3014 case HIER_P_HYBRID: 3015 return "Hybrid Hier-P"; 3016 default: 3017 return "No hier"; 3018 } 3019 } 3020 3021 inline const char* bitrate_type_string(int val) 3022 { 3023 switch(val) 3024 { 3025 case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE: 3026 return "CUMULATIVE"; 3027 case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE: 3028 return "LAYER WISE"; 3029 default: 3030 return "Unknown Bitrate Type"; 3031 } 3032 } 3033 3034 static const char *codec_as_string(unsigned long codec) { 3035 switch (codec) { 3036 case V4L2_PIX_FMT_H264: 3037 return "H264"; 3038 case V4L2_PIX_FMT_MPEG4: 3039 return "MPEG4"; 3040 case V4L2_PIX_FMT_H263: 3041 return "H263"; 3042 case V4L2_PIX_FMT_HEVC: 3043 return "HEVC"; 3044 case V4L2_PIX_FMT_VP8: 3045 return "VP8"; 3046 default: 3047 return "UNKOWN"; 3048 } 3049 } 3050 3051 void venc_dev::venc_config_print() 3052 { 3053 3054 DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld", 3055 codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level); 3056 3057 DEBUG_PRINT_HIGH("ENC_CONFIG: Input Width: %ld, Height:%ld, Fps: %ld", 3058 m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, 3059 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); 3060 3061 DEBUG_PRINT_HIGH("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld", 3062 m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height, 3063 m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); 3064 3065 DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u", 3066 color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs); 3067 3068 DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld", 3069 bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes); 3070 3071 DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld", 3072 session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp); 3073 3074 DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld", 3075 init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp); 3076 3077 DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu", 3078 session_qp_values.minqp, session_qp_values.maxqp); 3079 3080 DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld", 3081 voptimecfg.voptime_resolution, multislice.mslice_mode, 3082 multislice.mslice_size); 3083 3084 DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld", 3085 entropy.longentropysel, entropy.cabacmodel); 3086 3087 DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld", 3088 dbkfilter.db_mode, dbkfilter.slicealpha_offset, 3089 dbkfilter.slicebeta_offset); 3090 3091 DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld", 3092 intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod); 3093 3094 DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d", 3095 ltrinfo.enabled, ltrinfo.count); 3096 3097 if (temporal_layers_config.nPLayers) { 3098 DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu", 3099 temporal_layers_config.nPLayers, temporal_layers_config.nBLayers, 3100 intra_period.num_pframes + intra_period.num_bframes + 1); 3101 3102 for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid 3103 && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) { 3104 DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%", 3105 l, temporal_layers_config.nTemporalLayerBitrateFraction[l]); 3106 } 3107 } else { 3108 3109 DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d", 3110 hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable); 3111 3112 DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d", 3113 hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer); 3114 3115 DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d", 3116 hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1], 3117 hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3], 3118 hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]); 3119 } 3120 3121 DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel); 3122 3123 DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled); 3124 3125 DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate); 3126 3127 DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority); 3128 3129 DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate); 3130 } 3131 3132 bool venc_dev::venc_reconfig_reqbufs() 3133 { 3134 struct v4l2_requestbuffers bufreq; 3135 3136 bufreq.memory = V4L2_MEMORY_USERPTR; 3137 bufreq.count = m_sInput_buff_property.actualcount; 3138 bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3139 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 3140 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume"); 3141 return false; 3142 } 3143 3144 bufreq.memory = V4L2_MEMORY_USERPTR; 3145 bufreq.count = m_sOutput_buff_property.actualcount; 3146 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3147 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) 3148 { 3149 DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume"); 3150 return false; 3151 } 3152 return true; 3153 } 3154 3155 unsigned venc_dev::venc_flush( unsigned port) 3156 { 3157 struct v4l2_encoder_cmd enc; 3158 DEBUG_PRINT_LOW("in %s", __func__); 3159 3160 enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH; 3161 enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE; 3162 3163 if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) { 3164 DEBUG_PRINT_ERROR("Flush Port (%d) Failed ", port); 3165 return -1; 3166 } 3167 3168 return 0; 3169 3170 } 3171 3172 //allocating I/P memory from pmem and register with the device 3173 3174 3175 bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index) 3176 { 3177 3178 struct pmem *pmem_tmp; 3179 struct v4l2_buffer buf; 3180 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 3181 int rc = 0; 3182 unsigned int extra_idx; 3183 3184 pmem_tmp = (struct pmem *)buf_addr; 3185 DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp); 3186 3187 if (port == PORT_INDEX_OUT) { 3188 extra_idx = EXTRADATA_IDX(num_output_planes); 3189 buf.index = index; 3190 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3191 buf.memory = V4L2_MEMORY_USERPTR; 3192 plane[0].length = pmem_tmp->size; 3193 plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; 3194 plane[0].reserved[0] = pmem_tmp->fd; 3195 plane[0].reserved[1] = 0; 3196 plane[0].data_offset = pmem_tmp->offset; 3197 buf.m.planes = plane; 3198 buf.length = num_output_planes; 3199 3200 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 3201 char *userptr; 3202 int fd; 3203 unsigned offset; 3204 ssize_t size; 3205 int rc = mOutputExtradata.peek(index, &userptr, &fd, &offset, &size); 3206 if (rc != OMX_ErrorNone) { 3207 DEBUG_PRINT_ERROR("Unable to get extradata memory 2"); 3208 return rc; 3209 } 3210 plane[extra_idx].length = size; 3211 plane[extra_idx].m.userptr = (unsigned long)userptr; 3212 #ifdef USE_ION 3213 plane[extra_idx].reserved[0] = fd; 3214 #endif 3215 plane[extra_idx].reserved[1] = offset; 3216 plane[extra_idx].data_offset = 0; 3217 } else if (extra_idx >= VIDEO_MAX_PLANES) { 3218 DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx); 3219 return OMX_ErrorBadParameter; 3220 } 3221 3222 rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); 3223 3224 if (rc) 3225 DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed"); 3226 } else if (port == PORT_INDEX_IN) { 3227 DEBUG_PRINT_LOW("No need to call VIDIOC_PREPARE_BUF on input port"); 3228 } else { 3229 DEBUG_PRINT_ERROR("ERROR: venc_use_buf:Invalid Port Index "); 3230 return false; 3231 } 3232 3233 return true; 3234 } 3235 3236 bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) 3237 { 3238 struct pmem *pmem_tmp; 3239 struct venc_bufferpayload dev_buffer; 3240 3241 memset(&dev_buffer, 0, sizeof(dev_buffer)); 3242 pmem_tmp = (struct pmem *)buf_addr; 3243 3244 if (port == PORT_INDEX_IN) { 3245 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 3246 dev_buffer.fd = pmem_tmp->fd; 3247 dev_buffer.maped_size = pmem_tmp->size; 3248 dev_buffer.sz = pmem_tmp->size; 3249 dev_buffer.offset = pmem_tmp->offset; 3250 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \ 3251 dev_buffer.pbuffer, \ 3252 dev_buffer.fd, \ 3253 dev_buffer.offset, \ 3254 dev_buffer.maped_size); 3255 3256 } else if (port == PORT_INDEX_OUT) { 3257 dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; 3258 dev_buffer.fd = pmem_tmp->fd; 3259 dev_buffer.sz = pmem_tmp->size; 3260 dev_buffer.maped_size = pmem_tmp->size; 3261 dev_buffer.offset = pmem_tmp->offset; 3262 3263 DEBUG_PRINT_LOW("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \ 3264 dev_buffer.pbuffer, \ 3265 dev_buffer.fd, \ 3266 dev_buffer.offset, \ 3267 dev_buffer.maped_size); 3268 } else { 3269 DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index "); 3270 return false; 3271 } 3272 3273 return true; 3274 } 3275 3276 bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer, 3277 OMX_U32 width, OMX_U32 height) 3278 { 3279 OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width), 3280 y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height), 3281 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width), 3282 uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height), 3283 src_chroma_offset = width * height; 3284 3285 if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) { 3286 OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer; 3287 //Do chroma first, so that we can convert it in-place 3288 src_buf += width * height; 3289 dst_buf += y_stride * y_scanlines; 3290 for (int line = height / 2 - 1; line >= 0; --line) { 3291 memmove(dst_buf + line * uv_stride, 3292 src_buf + line * width, 3293 width); 3294 } 3295 3296 dst_buf = src_buf = buffer->pBuffer; 3297 //Copy the Y next 3298 for (int line = height - 1; line > 0; --line) { 3299 memmove(dst_buf + line * y_stride, 3300 src_buf + line * width, 3301 width); 3302 } 3303 } else { 3304 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \ 3305 Insufficient bufferLen=%u v/s Required=%u", 3306 (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen, 3307 VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)); 3308 return false; 3309 } 3310 3311 return true; 3312 } 3313 3314 bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel) 3315 { 3316 if (!perflevel) { 3317 DEBUG_PRINT_ERROR("Null pointer error"); 3318 return false; 3319 } else { 3320 *perflevel = performance_level.perflevel; 3321 return true; 3322 } 3323 } 3324 3325 bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled) 3326 { 3327 if (!enabled) { 3328 DEBUG_PRINT_ERROR("Null pointer error"); 3329 return false; 3330 } else { 3331 *enabled = vui_timing_info.enabled; 3332 return true; 3333 } 3334 } 3335 3336 bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled) 3337 { 3338 if (!enabled) { 3339 DEBUG_PRINT_ERROR("Null pointer error"); 3340 return false; 3341 } else { 3342 *enabled = vqzip_sei_info.enabled; 3343 return true; 3344 } 3345 } 3346 3347 bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate) 3348 { 3349 if (!peakbitrate) { 3350 DEBUG_PRINT_ERROR("Null pointer error"); 3351 return false; 3352 } else { 3353 *peakbitrate = peak_bitrate.peakbitrate; 3354 return true; 3355 } 3356 } 3357 3358 bool venc_dev::venc_get_batch_size(OMX_U32 *size) 3359 { 3360 if (!size) { 3361 DEBUG_PRINT_ERROR("Null pointer error"); 3362 return false; 3363 } else { 3364 *size = mBatchSize; 3365 return true; 3366 } 3367 } 3368 3369 bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd) 3370 { 3371 struct pmem *temp_buffer; 3372 struct v4l2_buffer buf; 3373 struct v4l2_requestbuffers bufreq; 3374 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 3375 int rc = 0, extra_idx; 3376 struct OMX_BUFFERHEADERTYPE *bufhdr; 3377 encoder_media_buffer_type * meta_buf = NULL; 3378 temp_buffer = (struct pmem *)buffer; 3379 3380 memset (&buf, 0, sizeof(buf)); 3381 memset (&plane, 0, sizeof(plane)); 3382 3383 if (buffer == NULL) { 3384 DEBUG_PRINT_ERROR("ERROR: venc_etb: buffer is NULL"); 3385 return false; 3386 } 3387 3388 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 3389 bufreq.memory = V4L2_MEMORY_USERPTR; 3390 bufreq.count = m_sInput_buff_property.actualcount; 3391 bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3392 3393 DEBUG_PRINT_LOW("Input buffer length %u", (unsigned int)bufhdr->nFilledLen); 3394 3395 if (pmem_data_buf) { 3396 DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); 3397 plane[0].m.userptr = (unsigned long)pmem_data_buf; 3398 plane[0].data_offset = bufhdr->nOffset; 3399 plane[0].length = bufhdr->nAllocLen; 3400 plane[0].bytesused = bufhdr->nFilledLen; 3401 } else { 3402 // -------------------------------------------------------------------------------------- 3403 // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info] 3404 // --------------------------------------------------------------------------------------- 3405 // Camera-2 1 CameraSource 0 meta-handle 3406 // Camera-3 1 GrallocSource 0 gralloc-private-handle 3407 // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted) 3408 // CPU (Eg: MediaCodec) 0 -- 0 bufhdr 3409 // --------------------------------------------------------------------------------------- 3410 if (metadatamode) { 3411 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer; 3412 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer; 3413 3414 if (!meta_buf) { 3415 //empty EOS buffer 3416 if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) { 3417 plane[0].data_offset = bufhdr->nOffset; 3418 plane[0].length = bufhdr->nAllocLen; 3419 plane[0].bytesused = bufhdr->nFilledLen; 3420 DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer"); 3421 } else { 3422 return false; 3423 } 3424 } else if (!color_format) { 3425 int usage = 0; 3426 3427 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) { 3428 native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle; 3429 if (!hnd) { 3430 DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL"); 3431 return false; 3432 } 3433 3434 if (!mBatchSize && hnd->numFds + hnd->numInts > 3) { 3435 usage = hnd->data[3]; 3436 } else if (mBatchSize) { 3437 usage = BatchInfo::getColorFormatAt(hnd, 0); 3438 } 3439 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) { 3440 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP; 3441 } 3442 3443 if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 || 3444 m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) { 3445 struct v4l2_format fmt; 3446 3447 memset(&fmt, 0, sizeof(fmt)); 3448 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 || 3449 usage & private_handle_t::PRIV_FLAGS_ITU_R_601) { 3450 DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR."); 3451 DEBUG_PRINT_ERROR(" This leads to unknown color space"); 3452 } 3453 if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) { 3454 if (is_csc_enabled) { 3455 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP; 3456 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; 3457 venc_set_colorspace(MSM_VIDC_BT709_5, 1, 3458 MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5); 3459 } else { 3460 venc_set_colorspace(MSM_VIDC_BT601_6_525, 1, 3461 MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525); 3462 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; 3463 } 3464 } 3465 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3466 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 3467 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 3468 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 3469 if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 3470 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC; 3471 } 3472 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 3473 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 3474 DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat); 3475 return false; 3476 } 3477 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 3478 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed"); 3479 return false; 3480 } 3481 } 3482 3483 // Setting batch mode is sticky. We do not expect camera to change 3484 // between batch and normal modes at runtime. 3485 if (mBatchSize) { 3486 if ((unsigned)hnd->numFds != mBatchSize) { 3487 DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)", 3488 mBatchSize, hnd->numFds); 3489 return false; 3490 } 3491 3492 return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index); 3493 } 3494 3495 if (hnd->numFds + hnd->numInts > 2) { 3496 plane[0].data_offset = hnd->data[1]; 3497 plane[0].length = hnd->data[2]; 3498 plane[0].bytesused = hnd->data[2]; 3499 } 3500 DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx", 3501 fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat); 3502 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) { 3503 private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle; 3504 if (!streaming[OUTPUT_PORT] && handle) { 3505 3506 // Moment of truth... actual colorspace is known here.. 3507 ColorSpace_t colorSpace = ITU_R_601; 3508 if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) { 3509 DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)", 3510 colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709); 3511 } 3512 3513 struct v4l2_format fmt; 3514 memset(&fmt, 0, sizeof(fmt)); 3515 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3516 3517 bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc; 3518 if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { 3519 m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12; 3520 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear"); 3521 } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { 3522 // In case of RGB, conversion to YUV is handled within encoder. 3523 // Disregard the Colorspace in gralloc-handle in case of RGB and use 3524 // [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR 3525 // [b] 601 for UBWC case : Venus can convert to 601-LR or FR. use LR for now. 3526 colorSpace = ITU_R_601; 3527 m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32; 3528 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear"); 3529 } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) { 3530 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 3531 DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear"); 3532 } 3533 3534 // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC 3535 if (colorSpace == ITU_R_601_FR && is_csc_enabled) { 3536 struct v4l2_control control; 3537 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC; 3538 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE; 3539 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 3540 DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709"); 3541 } else { 3542 DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709"); 3543 buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP; 3544 colorSpace = ITU_R_709; 3545 } 3546 } 3547 3548 msm_vidc_h264_color_primaries_values primary; 3549 msm_vidc_h264_transfer_chars_values transfer; 3550 msm_vidc_h264_matrix_coeff_values matrix; 3551 OMX_U32 range; 3552 3553 switch (colorSpace) { 3554 case ITU_R_601_FR: 3555 { 3556 primary = MSM_VIDC_BT601_6_525; 3557 range = 1; // full 3558 transfer = MSM_VIDC_TRANSFER_601_6_525; 3559 matrix = MSM_VIDC_MATRIX_601_6_525; 3560 3561 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; 3562 break; 3563 } 3564 case ITU_R_709: 3565 { 3566 primary = MSM_VIDC_BT709_5; 3567 range = 0; // limited 3568 transfer = MSM_VIDC_TRANSFER_BT709_5; 3569 matrix = MSM_VIDC_MATRIX_BT_709_5; 3570 3571 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; 3572 break; 3573 } 3574 default: 3575 { 3576 // 601 or something else ? assume 601 3577 primary = MSM_VIDC_BT601_6_625; 3578 range = 0; //limited 3579 transfer = MSM_VIDC_TRANSFER_601_6_625; 3580 matrix = MSM_VIDC_MATRIX_601_6_625; 3581 3582 fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; 3583 break; 3584 } 3585 } 3586 DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)", 3587 colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709); 3588 venc_set_colorspace(primary, range, transfer, matrix); 3589 3590 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 3591 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 3592 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 3593 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 3594 DEBUG_PRINT_ERROR("Failed setting color format in Grallocsource %lx", m_sVenc_cfg.inputformat); 3595 return false; 3596 } 3597 if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 3598 DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed"); 3599 return false; 3600 } 3601 } 3602 3603 fd = handle->fd; 3604 plane[0].data_offset = 0; 3605 plane[0].length = handle->size; 3606 plane[0].bytesused = handle->size; 3607 DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d " 3608 ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat); 3609 } 3610 } else { 3611 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer; 3612 plane[0].data_offset = bufhdr->nOffset; 3613 plane[0].length = bufhdr->nAllocLen; 3614 plane[0].bytesused = bufhdr->nFilledLen; 3615 DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d", 3616 fd, plane[0].bytesused, plane[0].length); 3617 } 3618 } else { 3619 plane[0].m.userptr = (unsigned long) bufhdr->pBuffer; 3620 plane[0].data_offset = bufhdr->nOffset; 3621 plane[0].length = bufhdr->nAllocLen; 3622 plane[0].bytesused = bufhdr->nFilledLen; 3623 DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d", 3624 fd, plane[0].bytesused, plane[0].length); 3625 } 3626 } 3627 3628 extra_idx = EXTRADATA_IDX(num_input_planes); 3629 3630 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 3631 char *userptr; 3632 int fd; 3633 unsigned offset; 3634 ssize_t size; 3635 int rc = mInputExtradata.get(bufhdr, &userptr, &fd, &offset, &size); 3636 if (rc != OMX_ErrorNone) { 3637 DEBUG_PRINT_ERROR("Unable to get extradata memory 1"); 3638 return rc; 3639 } 3640 plane[extra_idx].bytesused = 0; 3641 plane[extra_idx].length = size; 3642 plane[extra_idx].m.userptr = (unsigned long) userptr; 3643 #ifdef USE_ION 3644 plane[extra_idx].reserved[0] = fd; 3645 #endif 3646 plane[extra_idx].reserved[1] = offset; 3647 plane[extra_idx].data_offset = 0; 3648 } else if (extra_idx >= VIDEO_MAX_PLANES) { 3649 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); 3650 return false; 3651 } 3652 3653 buf.index = index; 3654 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3655 buf.memory = V4L2_MEMORY_USERPTR; 3656 plane[0].reserved[0] = fd; 3657 plane[0].reserved[1] = 0; 3658 buf.m.planes = plane; 3659 buf.length = num_input_planes; 3660 3661 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) 3662 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS; 3663 3664 buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000; 3665 buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000); 3666 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 3667 3668 if (rc) { 3669 DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver"); 3670 return false; 3671 } 3672 3673 etb++; 3674 3675 if (!streaming[OUTPUT_PORT]) { 3676 enum v4l2_buf_type buf_type; 3677 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3678 int ret; 3679 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type); 3680 3681 if (ret) { 3682 DEBUG_PRINT_ERROR("Failed to call streamon"); 3683 if (errno == EBUSY) { 3684 hw_overload = true; 3685 } 3686 return false; 3687 } else { 3688 streaming[OUTPUT_PORT] = true; 3689 } 3690 } 3691 if (m_debug.in_buffer_log) { 3692 venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat); 3693 } 3694 3695 return true; 3696 } 3697 3698 bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index) 3699 { 3700 struct v4l2_buffer buf; 3701 struct v4l2_plane plane; 3702 int rc = 0; 3703 struct v4l2_control control; 3704 encoder_media_buffer_type * meta_buf = NULL; 3705 native_handle_t *hnd = NULL; 3706 3707 if (bufhdr == NULL) { 3708 DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__); 3709 return false; 3710 } 3711 3712 bool status = true; 3713 if (metadatamode) { 3714 plane.m.userptr = (unsigned long)bufhdr->pBuffer; 3715 meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer; 3716 3717 if (!color_format) { 3718 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) { 3719 hnd = (native_handle_t*)meta_buf->meta_handle; 3720 if (!hnd) { 3721 DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !"); 3722 return false; 3723 } else if (hnd->numFds > kMaxBuffersInBatch) { 3724 DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. " 3725 "Max = %d", hnd->numFds, kMaxBuffersInBatch); 3726 status = false; 3727 } 3728 DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds); 3729 } else { 3730 DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !"); 3731 status = false; 3732 } 3733 } else { 3734 DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !"); 3735 status = false; 3736 } 3737 } else { 3738 DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !"); 3739 status = false; 3740 } 3741 3742 if (status) { 3743 OMX_TICKS bufTimeStamp = 0ll; 3744 int numBufs = hnd->numFds; 3745 int v4l2Ids[kMaxBuffersInBatch] = {-1}; 3746 for (int i = 0; i < numBufs; ++i) { 3747 v4l2Ids[i] = mBatchInfo.registerBuffer(index); 3748 if (v4l2Ids[i] < 0) { 3749 DEBUG_PRINT_ERROR("Failed to register buffer"); 3750 // TODO: cleanup the map and purge all slots of current index 3751 status = false; 3752 break; 3753 } 3754 } 3755 for (int i = 0; i < numBufs; ++i) { 3756 int v4l2Id = v4l2Ids[i]; 3757 3758 memset(&buf, 0, sizeof(buf)); 3759 memset(&plane, 0, sizeof(plane)); 3760 3761 DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id); 3762 buf.index = (unsigned)v4l2Id; 3763 buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3764 buf.memory = V4L2_MEMORY_USERPTR; 3765 plane.reserved[0] = BatchInfo::getFdAt(hnd, i); 3766 plane.reserved[1] = 0; 3767 plane.data_offset = BatchInfo::getOffsetAt(hnd, i); 3768 plane.m.userptr = (unsigned long)meta_buf; 3769 plane.length = plane.bytesused = BatchInfo::getSizeAt(hnd, i); 3770 buf.m.planes = &plane; 3771 buf.length = 1; 3772 3773 if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) 3774 buf.flags |= V4L2_QCOM_BUF_FLAG_EOS; 3775 if (i != numBufs - 1) { 3776 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER; 3777 DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer", 3778 i, etb + 1, numBufs); 3779 } 3780 3781 3782 // timestamp differences from camera are in nano-seconds 3783 bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000; 3784 3785 DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld", 3786 i, numBufs, bufhdr, plane.reserved[0], plane.length, bufTimeStamp); 3787 buf.timestamp.tv_sec = bufTimeStamp / 1000000; 3788 buf.timestamp.tv_usec = (bufTimeStamp % 1000000); 3789 3790 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 3791 if (rc) { 3792 DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__); 3793 return false; 3794 } 3795 3796 etb++; 3797 } 3798 } 3799 3800 if (status && !streaming[OUTPUT_PORT]) { 3801 enum v4l2_buf_type buf_type; 3802 buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 3803 int ret; 3804 ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type); 3805 if (ret) { 3806 DEBUG_PRINT_ERROR("Failed to call streamon"); 3807 if (errno == EBUSY) { 3808 hw_overload = true; 3809 } 3810 status = false; 3811 } else { 3812 streaming[OUTPUT_PORT] = true; 3813 } 3814 } 3815 3816 return status; 3817 } 3818 3819 bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) 3820 { 3821 struct pmem *temp_buffer = NULL; 3822 struct venc_buffer frameinfo; 3823 struct v4l2_buffer buf; 3824 struct v4l2_plane plane[VIDEO_MAX_PLANES]; 3825 int rc = 0; 3826 unsigned int extra_idx; 3827 struct OMX_BUFFERHEADERTYPE *bufhdr; 3828 3829 if (buffer == NULL) 3830 return false; 3831 3832 bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; 3833 3834 if (pmem_data_buf) { 3835 DEBUG_PRINT_LOW("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); 3836 plane[0].m.userptr = (unsigned long)pmem_data_buf; 3837 } else { 3838 DEBUG_PRINT_LOW("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); 3839 plane[0].m.userptr = (unsigned long)bufhdr->pBuffer; 3840 } 3841 3842 memset(&buf, 0, sizeof(buf)); 3843 memset(&plane, 0, sizeof(plane)); 3844 3845 buf.index = index; 3846 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 3847 buf.memory = V4L2_MEMORY_USERPTR; 3848 plane[0].length = bufhdr->nAllocLen; 3849 plane[0].bytesused = bufhdr->nFilledLen; 3850 plane[0].reserved[0] = fd; 3851 plane[0].reserved[1] = 0; 3852 plane[0].data_offset = bufhdr->nOffset; 3853 buf.m.planes = plane; 3854 buf.length = num_output_planes; 3855 buf.flags = 0; 3856 3857 if (mBatchSize) { 3858 // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1 3859 // This results in the first batch being of size mBatchSize + 1, but thats good because 3860 // we need an extra FTB for the codec specific data. 3861 3862 if (!ftb || ftb % mBatchSize) { 3863 buf.flags |= V4L2_MSM_BUF_FLAG_DEFER; 3864 DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1); 3865 } 3866 } 3867 3868 extra_idx = EXTRADATA_IDX(num_output_planes); 3869 3870 if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { 3871 char *userptr; 3872 int fd; 3873 unsigned offset; 3874 ssize_t size; 3875 int rc = mOutputExtradata.get(&userptr, &fd, &offset, &size); 3876 if (rc != OMX_ErrorNone) { 3877 DEBUG_PRINT_ERROR("Unable to get extradata memory 0"); 3878 return false; 3879 } 3880 plane[extra_idx].bytesused = 0; 3881 plane[extra_idx].length = size; 3882 plane[extra_idx].m.userptr = (unsigned long)userptr; 3883 #ifdef USE_ION 3884 plane[extra_idx].reserved[0] = fd; 3885 #endif 3886 plane[extra_idx].reserved[1] = offset; 3887 plane[extra_idx].data_offset = 0; 3888 } else if (extra_idx >= VIDEO_MAX_PLANES) { 3889 DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx); 3890 return false; 3891 } 3892 3893 rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); 3894 3895 if (rc) { 3896 DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver"); 3897 return false; 3898 } 3899 3900 ftb++; 3901 return true; 3902 } 3903 3904 bool venc_dev::venc_set_inband_video_header(OMX_BOOL enable) 3905 { 3906 struct v4l2_control control; 3907 3908 control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; 3909 if(enable) { 3910 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME; 3911 } else { 3912 control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; 3913 } 3914 3915 DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable); 3916 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) { 3917 DEBUG_PRINT_ERROR("Request for inband sps/pps failed"); 3918 return false; 3919 } 3920 return true; 3921 } 3922 3923 bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable) 3924 { 3925 struct v4l2_control control; 3926 3927 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER; 3928 if(enable) { 3929 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED; 3930 } else { 3931 control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED; 3932 } 3933 3934 DEBUG_PRINT_HIGH("Set au delimiter: %d", enable); 3935 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) { 3936 DEBUG_PRINT_ERROR("Request to set AU delimiter failed"); 3937 return false; 3938 } 3939 return true; 3940 } 3941 3942 bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode) 3943 { 3944 struct v4l2_control control; 3945 3946 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE; 3947 control.value = mode; 3948 3949 DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode); 3950 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) { 3951 DEBUG_PRINT_ERROR("Setting MBI mode failed"); 3952 return false; 3953 } 3954 return true; 3955 } 3956 3957 bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable) 3958 { 3959 struct v4l2_control sei_control, yuvstats_control; 3960 3961 DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable); 3962 sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI; 3963 yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 3964 3965 if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) { 3966 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed"); 3967 } 3968 3969 if(enable) { 3970 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE; 3971 yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS; 3972 } else { 3973 sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE; 3974 yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS; 3975 } 3976 3977 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) { 3978 DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed"); 3979 } 3980 3981 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) { 3982 DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed"); 3983 } 3984 #ifdef _VQZIP_ 3985 vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16); 3986 vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16); 3987 vqzip.init(); 3988 vqzip_sei_info.enabled = true; 3989 #endif 3990 3991 return true; 3992 } 3993 3994 bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode) 3995 { 3996 // Check for layers in Hier-p/hier-B with Hier-P-Hybrid 3997 if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID) 3998 return false; 3999 4000 // Check for bframes with Hier-P-Hybrid 4001 if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID) 4002 return false; 4003 4004 // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B 4005 if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P || 4006 hier_layers.hier_mode == HIER_B || ltrinfo.count)) 4007 return false; 4008 4009 // Check for LTR with Hier-P-Hybrid 4010 if (count && hier_layers.hier_mode == HIER_P_HYBRID) 4011 return false; 4012 4013 return true; 4014 } 4015 4016 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type, 4017 OMX_U32 num_layers) 4018 { 4019 struct v4l2_control control; 4020 4021 if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){ 4022 DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP"); 4023 return false; 4024 } 4025 4026 if (type == QOMX_HIERARCHICALCODING_P) { 4027 // Reduce layer count by 1 before sending to driver. This avoids 4028 // driver doing the same in multiple places. 4029 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS; 4030 control.value = num_layers - 1; 4031 DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers); 4032 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 4033 DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed"); 4034 return false; 4035 } 4036 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS; 4037 control.value = num_layers - 1; 4038 DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers); 4039 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 4040 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed"); 4041 return false; 4042 } 4043 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4044 DEBUG_PRINT_LOW("Set H264_SVC_NAL"); 4045 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC; 4046 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED; 4047 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 4048 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL"); 4049 return false; 4050 } 4051 } 4052 hier_layers.hier_mode = HIER_P; 4053 } else if (type == QOMX_HIERARCHICALCODING_B) { 4054 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) { 4055 DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode"); 4056 return false; 4057 } 4058 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS; 4059 control.value = num_layers - 1; 4060 DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers); 4061 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 4062 DEBUG_PRINT_ERROR("Request to set Hier P num layers failed"); 4063 return false; 4064 } 4065 hier_layers.hier_mode = HIER_B; 4066 } else { 4067 DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type); 4068 return false; 4069 } 4070 hier_layers.numlayers = num_layers; 4071 return true; 4072 } 4073 4074 bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable) 4075 { 4076 struct v4l2_control control; 4077 4078 DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data); 4079 4080 if (enable == OMX_FALSE) { 4081 /* No easy way to turn off extradata to the driver 4082 * at the moment */ 4083 return false; 4084 } 4085 4086 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; 4087 switch (extra_data) { 4088 case OMX_ExtraDataVideoEncoderSliceInfo: 4089 control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO; 4090 break; 4091 case OMX_ExtraDataVideoEncoderMBInfo: 4092 control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI; 4093 break; 4094 case OMX_ExtraDataFrameDimension: 4095 control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP; 4096 break; 4097 default: 4098 DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data); 4099 return false; 4100 } 4101 4102 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 4103 DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d", 4104 (unsigned int)extra_data, errno); 4105 return false; 4106 } 4107 4108 return true; 4109 } 4110 4111 bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable) 4112 { 4113 struct v4l2_control control; 4114 4115 if (enable) { 4116 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE; 4117 control.value = 1; 4118 DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value); 4119 4120 if (multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4121 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 4122 DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); 4123 return false; 4124 } else { 4125 DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d", control.id, control.value); 4126 slice_mode.enable = 1; 4127 } 4128 } else { 4129 DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] " 4130 "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode, 4131 m_sVenc_cfg.codectype); 4132 } 4133 } else { 4134 DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled"); 4135 } 4136 4137 return true; 4138 } 4139 4140 bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp) 4141 { 4142 int rc; 4143 struct v4l2_control control; 4144 struct v4l2_ext_control ctrl[4]; 4145 struct v4l2_ext_controls controls; 4146 4147 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP; 4148 ctrl[0].value = initqp->nQpI; 4149 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP; 4150 ctrl[1].value = initqp->nQpP; 4151 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP; 4152 ctrl[2].value = initqp->nQpB; 4153 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP; 4154 ctrl[3].value = initqp->bEnableInitQp; 4155 4156 controls.count = 4; 4157 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 4158 controls.controls = ctrl; 4159 4160 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d", 4161 controls.controls[0].id, controls.controls[0].value, 4162 controls.controls[1].id, controls.controls[1].value, 4163 controls.controls[2].id, controls.controls[2].value, 4164 controls.controls[3].id, controls.controls[3].value); 4165 4166 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 4167 if (rc) { 4168 DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc); 4169 return false; 4170 } 4171 4172 init_qp.iframeqp = initqp->nQpI; 4173 init_qp.pframeqp = initqp->nQpP; 4174 init_qp.bframeqp = initqp->nQpB; 4175 init_qp.enableinitqp = initqp->bEnableInitQp; 4176 4177 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d", 4178 controls.controls[0].id, controls.controls[0].value, 4179 controls.controls[1].id, controls.controls[1].value, 4180 controls.controls[2].id, controls.controls[2].value, 4181 controls.controls[3].id, controls.controls[3].value); 4182 return true; 4183 } 4184 4185 bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range, 4186 OMX_U32 transfer_chars, OMX_U32 matrix_coeffs) 4187 { 4188 int rc; 4189 struct v4l2_control control; 4190 4191 DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d", 4192 primaries, range, transfer_chars, matrix_coeffs); 4193 4194 control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE; 4195 control.value = primaries; 4196 4197 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4198 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4199 4200 if (rc) { 4201 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE"); 4202 return false; 4203 } 4204 4205 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4206 4207 color_space.primaries = control.value; 4208 4209 control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE; 4210 control.value = range; 4211 4212 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4213 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4214 4215 if (rc) { 4216 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE"); 4217 return false; 4218 } 4219 4220 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4221 4222 color_space.range = control.value; 4223 4224 control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS; 4225 control.value = transfer_chars; 4226 4227 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4228 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4229 4230 if (rc) { 4231 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS"); 4232 return false; 4233 } 4234 4235 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4236 4237 color_space.transfer_chars = control.value; 4238 4239 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS; 4240 control.value = matrix_coeffs; 4241 4242 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4243 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4244 4245 if (rc) { 4246 DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS"); 4247 return false; 4248 } 4249 4250 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4251 4252 color_space.matrix_coeffs = control.value; 4253 4254 return true; 4255 } 4256 4257 bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp) 4258 { 4259 int rc; 4260 struct v4l2_control control; 4261 4262 control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; 4263 control.value = i_frame_qp; 4264 4265 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4266 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4267 4268 if (rc) { 4269 DEBUG_PRINT_ERROR("Failed to set control"); 4270 return false; 4271 } 4272 4273 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4274 session_qp.iframeqp = control.value; 4275 4276 control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; 4277 control.value = p_frame_qp; 4278 4279 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4280 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4281 4282 if (rc) { 4283 DEBUG_PRINT_ERROR("Failed to set control"); 4284 return false; 4285 } 4286 4287 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4288 4289 session_qp.pframeqp = control.value; 4290 4291 if ((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) || 4292 (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { 4293 4294 control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; 4295 control.value = b_frame_qp; 4296 4297 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4298 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4299 4300 if (rc) { 4301 DEBUG_PRINT_ERROR("Failed to set control"); 4302 return false; 4303 } 4304 4305 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4306 4307 session_qp.bframeqp = control.value; 4308 } 4309 4310 return true; 4311 } 4312 4313 bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp) 4314 { 4315 int rc; 4316 struct v4l2_control control; 4317 4318 if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) { 4319 4320 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) 4321 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP; 4322 else 4323 control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP; 4324 control.value = min_qp; 4325 4326 DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d", 4327 control.id, control.value); 4328 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4329 if (rc) { 4330 DEBUG_PRINT_ERROR("Failed to set control"); 4331 return false; 4332 } 4333 4334 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) 4335 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP; 4336 else 4337 control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP; 4338 control.value = max_qp; 4339 4340 DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d", 4341 control.id, control.value); 4342 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4343 if (rc) { 4344 DEBUG_PRINT_ERROR("Failed to set control"); 4345 return false; 4346 } 4347 } else { 4348 DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]", 4349 (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp); 4350 } 4351 4352 return true; 4353 } 4354 4355 bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) 4356 { 4357 struct venc_profile requested_profile = {0}; 4358 struct ven_profilelevel requested_level = {0}; 4359 unsigned long mb_per_frame = 0; 4360 DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %u, Level = %u", 4361 (unsigned int)eProfile, (unsigned int)eLevel); 4362 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)* 4363 ((m_sVenc_cfg.dvs_width + 15) >> 4); 4364 4365 if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) { 4366 DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start"); 4367 return true; 4368 } 4369 4370 if (vqzip_sei_info.enabled) { 4371 DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation"); 4372 return true; 4373 } 4374 4375 DEBUG_PRINT_LOW("Validating Profile/Level from table"); 4376 4377 if (!venc_validate_profile_level(&eProfile, &eLevel)) { 4378 DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed"); 4379 return false; 4380 } 4381 4382 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 4383 DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and " 4384 "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)eProfile, 4385 OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); 4386 4387 if (eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 4388 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; 4389 } else if (eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 4390 requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE; 4391 } else { 4392 DEBUG_PRINT_LOW("ERROR: Unsupported MPEG4 profile = %u", 4393 (unsigned int)eProfile); 4394 return false; 4395 } 4396 4397 DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," 4398 "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," 4399 "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, 4400 OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); 4401 4402 if (mb_per_frame >= 3600) { 4403 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) 4404 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 4405 4406 if (requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) 4407 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 4408 } else { 4409 switch (eLevel) { 4410 case OMX_VIDEO_MPEG4Level0: 4411 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0; 4412 break; 4413 case OMX_VIDEO_MPEG4Level0b: 4414 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B; 4415 break; 4416 case OMX_VIDEO_MPEG4Level1: 4417 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1; 4418 break; 4419 case OMX_VIDEO_MPEG4Level2: 4420 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; 4421 break; 4422 case OMX_VIDEO_MPEG4Level3: 4423 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3; 4424 break; 4425 case OMX_VIDEO_MPEG4Level4a: 4426 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4; 4427 break; 4428 case OMX_VIDEO_MPEG4Level5: 4429 requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 4430 break; 4431 default: 4432 return false; 4433 // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 4434 break; 4435 } 4436 } 4437 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 4438 4439 switch (eProfile) { 4440 case OMX_VIDEO_H263ProfileBaseline: 4441 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE; 4442 break; 4443 case OMX_VIDEO_H263ProfileH320Coding: 4444 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING; 4445 break; 4446 case OMX_VIDEO_H263ProfileBackwardCompatible: 4447 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE; 4448 break; 4449 case OMX_VIDEO_H263ProfileISWV2: 4450 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2; 4451 break; 4452 case OMX_VIDEO_H263ProfileISWV3: 4453 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3; 4454 break; 4455 case OMX_VIDEO_H263ProfileHighCompression: 4456 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION; 4457 break; 4458 case OMX_VIDEO_H263ProfileInternet: 4459 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET; 4460 break; 4461 case OMX_VIDEO_H263ProfileInterlace: 4462 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE; 4463 break; 4464 case OMX_VIDEO_H263ProfileHighLatency: 4465 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY; 4466 break; 4467 default: 4468 DEBUG_PRINT_LOW("ERROR: Unsupported H.263 profile = %lu", 4469 requested_profile.profile); 4470 return false; 4471 } 4472 4473 //profile level 4474 switch (eLevel) { 4475 case OMX_VIDEO_H263Level10: 4476 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0; 4477 break; 4478 case OMX_VIDEO_H263Level20: 4479 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0; 4480 break; 4481 case OMX_VIDEO_H263Level30: 4482 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0; 4483 break; 4484 case OMX_VIDEO_H263Level40: 4485 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0; 4486 break; 4487 case OMX_VIDEO_H263Level45: 4488 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5; 4489 break; 4490 case OMX_VIDEO_H263Level50: 4491 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0; 4492 break; 4493 case OMX_VIDEO_H263Level60: 4494 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0; 4495 break; 4496 case OMX_VIDEO_H263Level70: 4497 requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0; 4498 break; 4499 default: 4500 return false; 4501 break; 4502 } 4503 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4504 if (eProfile == OMX_VIDEO_AVCProfileBaseline) { 4505 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; 4506 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) { 4507 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE; 4508 } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh) { 4509 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH; 4510 } else if (eProfile == OMX_VIDEO_AVCProfileMain) { 4511 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN; 4512 } else if (eProfile == OMX_VIDEO_AVCProfileExtended) { 4513 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED; 4514 } else if (eProfile == OMX_VIDEO_AVCProfileHigh) { 4515 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; 4516 } else if (eProfile == OMX_VIDEO_AVCProfileHigh10) { 4517 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10; 4518 } else if (eProfile == OMX_VIDEO_AVCProfileHigh422) { 4519 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422; 4520 } else if (eProfile == OMX_VIDEO_AVCProfileHigh444) { 4521 requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE; 4522 } else { 4523 DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %lu", 4524 requested_profile.profile); 4525 return false; 4526 } 4527 4528 //profile level 4529 switch (eLevel) { 4530 case OMX_VIDEO_AVCLevel1: 4531 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; 4532 break; 4533 case OMX_VIDEO_AVCLevel1b: 4534 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B; 4535 break; 4536 case OMX_VIDEO_AVCLevel11: 4537 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1; 4538 break; 4539 case OMX_VIDEO_AVCLevel12: 4540 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2; 4541 break; 4542 case OMX_VIDEO_AVCLevel13: 4543 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3; 4544 break; 4545 case OMX_VIDEO_AVCLevel2: 4546 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0; 4547 break; 4548 case OMX_VIDEO_AVCLevel21: 4549 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1; 4550 break; 4551 case OMX_VIDEO_AVCLevel22: 4552 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2; 4553 break; 4554 case OMX_VIDEO_AVCLevel3: 4555 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0; 4556 break; 4557 case OMX_VIDEO_AVCLevel31: 4558 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1; 4559 break; 4560 case OMX_VIDEO_AVCLevel32: 4561 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2; 4562 break; 4563 case OMX_VIDEO_AVCLevel4: 4564 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; 4565 break; 4566 case OMX_VIDEO_AVCLevel41: 4567 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; 4568 break; 4569 case OMX_VIDEO_AVCLevel42: 4570 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2; 4571 break; 4572 case OMX_VIDEO_AVCLevel5: 4573 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0; 4574 break; 4575 case OMX_VIDEO_AVCLevel51: 4576 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1; 4577 break; 4578 case OMX_VIDEO_AVCLevel52: 4579 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2; 4580 break; 4581 case OMX_VIDEO_AVCLevelMax: 4582 requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2; 4583 break; 4584 default : 4585 DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu", 4586 requested_level.level); 4587 return false; 4588 break; 4589 } 4590 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 4591 if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) { 4592 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u", 4593 (unsigned int)eProfile); 4594 return false; 4595 } 4596 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED; 4597 m_profile_set = true; 4598 switch(eLevel) { 4599 case OMX_VIDEO_VP8Level_Version0: 4600 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0; 4601 break; 4602 case OMX_VIDEO_VP8Level_Version1: 4603 requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1; 4604 break; 4605 default: 4606 DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u", 4607 (unsigned int)eLevel); 4608 return false; 4609 break; 4610 } 4611 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 4612 if (eProfile == OMX_VIDEO_HEVCProfileMain) { 4613 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN; 4614 } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) { 4615 requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10; 4616 } else { 4617 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu", 4618 requested_profile.profile); 4619 return false; 4620 } 4621 4622 //profile level 4623 switch (eLevel) { 4624 case OMX_VIDEO_HEVCMainTierLevel1: 4625 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1; 4626 break; 4627 case OMX_VIDEO_HEVCHighTierLevel1: 4628 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1; 4629 break; 4630 case OMX_VIDEO_HEVCMainTierLevel2: 4631 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2; 4632 break; 4633 case OMX_VIDEO_HEVCHighTierLevel2: 4634 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2; 4635 break; 4636 case OMX_VIDEO_HEVCMainTierLevel21: 4637 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1; 4638 break; 4639 case OMX_VIDEO_HEVCHighTierLevel21: 4640 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1; 4641 break; 4642 case OMX_VIDEO_HEVCMainTierLevel3: 4643 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3; 4644 break; 4645 case OMX_VIDEO_HEVCHighTierLevel3: 4646 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3; 4647 break; 4648 case OMX_VIDEO_HEVCMainTierLevel31: 4649 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1; 4650 break; 4651 case OMX_VIDEO_HEVCHighTierLevel31: 4652 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1; 4653 break; 4654 case OMX_VIDEO_HEVCMainTierLevel4: 4655 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4; 4656 break; 4657 case OMX_VIDEO_HEVCHighTierLevel4: 4658 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4; 4659 break; 4660 case OMX_VIDEO_HEVCMainTierLevel41: 4661 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1; 4662 break; 4663 case OMX_VIDEO_HEVCHighTierLevel41: 4664 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1; 4665 break; 4666 case OMX_VIDEO_HEVCMainTierLevel5: 4667 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5; 4668 break; 4669 case OMX_VIDEO_HEVCHighTierLevel5: 4670 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5; 4671 break; 4672 case OMX_VIDEO_HEVCMainTierLevel51: 4673 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1; 4674 break; 4675 case OMX_VIDEO_HEVCHighTierLevel51: 4676 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1; 4677 break; 4678 case OMX_VIDEO_HEVCMainTierLevel52: 4679 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2; 4680 break; 4681 case OMX_VIDEO_HEVCHighTierLevel52: 4682 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2; 4683 break; 4684 case OMX_VIDEO_HEVCMainTierLevel6: 4685 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6; 4686 break; 4687 case OMX_VIDEO_HEVCHighTierLevel6: 4688 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6; 4689 break; 4690 case OMX_VIDEO_HEVCMainTierLevel61: 4691 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1; 4692 break; 4693 case OMX_VIDEO_HEVCHighTierLevel61: 4694 requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1; 4695 break; 4696 default : 4697 DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu", 4698 requested_level.level); 4699 return false; 4700 } 4701 } 4702 4703 if (!m_profile_set) { 4704 int rc; 4705 struct v4l2_control control; 4706 4707 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4708 control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; 4709 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 4710 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE; 4711 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 4712 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE; 4713 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 4714 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE; 4715 } else { 4716 DEBUG_PRINT_ERROR("Wrong CODEC"); 4717 return false; 4718 } 4719 4720 control.value = requested_profile.profile; 4721 4722 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4723 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4724 4725 if (rc) { 4726 DEBUG_PRINT_ERROR("Failed to set control"); 4727 return false; 4728 } 4729 4730 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4731 4732 codec_profile.profile = control.value; 4733 m_profile_set = true; 4734 } 4735 4736 if (!m_level_set) { 4737 int rc; 4738 struct v4l2_control control; 4739 4740 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 4741 control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; 4742 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 4743 control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL; 4744 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 4745 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL; 4746 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 4747 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL; 4748 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 4749 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL; 4750 } else { 4751 DEBUG_PRINT_ERROR("Wrong CODEC"); 4752 return false; 4753 } 4754 4755 control.value = requested_level.level; 4756 4757 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4758 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4759 4760 if (rc) { 4761 DEBUG_PRINT_ERROR("Failed to set control"); 4762 return false; 4763 } 4764 4765 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4766 4767 profile_level.level = control.value; 4768 m_level_set = true; 4769 } 4770 4771 return true; 4772 } 4773 4774 bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) 4775 { 4776 4777 struct venc_voptimingcfg vop_timing_cfg; 4778 4779 DEBUG_PRINT_LOW("venc_set_voptiming_cfg: TimeRes = %u", 4780 (unsigned int)TimeIncRes); 4781 4782 vop_timing_cfg.voptime_resolution = TimeIncRes; 4783 4784 voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; 4785 return true; 4786 } 4787 4788 bool venc_dev::venc_set_intra_period_config(OMX_U32 nPFrames, OMX_U32 nBFrames) { 4789 #if _ANDROID_ 4790 // Android defines nBFrames as number of Bs between I OR P 4791 // Per the spec, nBFrames is number of Bs between I 4792 OMX_U32 nBs = nBFrames * (nPFrames + 1); 4793 DEBUG_PRINT_INFO("Updating Bframes from %u to %u", nBFrames, nBs); 4794 nBFrames = nBs; 4795 #endif //_ANDROID_ 4796 return venc_set_intra_period(nPFrames, nBFrames); 4797 } 4798 4799 bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) 4800 { 4801 4802 DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames); 4803 int rc; 4804 struct v4l2_control control; 4805 int pframe = 0, bframe = 0; 4806 4807 if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) && 4808 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && 4809 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) && 4810 (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) && 4811 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) { 4812 nBFrames=0; 4813 } 4814 4815 if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) { 4816 DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP"); 4817 return false; 4818 } 4819 4820 intra_period.num_pframes = nPFrames; 4821 intra_period.num_bframes = nBFrames; 4822 4823 if (!venc_calibrate_gop() && !is_thulium_v1) 4824 { 4825 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes"); 4826 return false; 4827 } 4828 4829 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 4830 control.value = intra_period.num_pframes; 4831 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4832 4833 if (rc) { 4834 DEBUG_PRINT_ERROR("Failed to set control"); 4835 return false; 4836 } 4837 4838 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4839 4840 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; 4841 control.value = intra_period.num_bframes; 4842 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4843 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4844 4845 if (rc) { 4846 DEBUG_PRINT_ERROR("Failed to set control"); 4847 return false; 4848 } 4849 4850 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes); 4851 4852 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 || 4853 m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 4854 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 4855 control.value = 1; 4856 4857 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4858 4859 if (rc) { 4860 DEBUG_PRINT_ERROR("Failed to set control"); 4861 return false; 4862 } 4863 idrperiod.idrperiod = 1; 4864 } 4865 return true; 4866 } 4867 4868 bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod) 4869 { 4870 int rc = 0; 4871 struct v4l2_control control; 4872 DEBUG_PRINT_LOW("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u", 4873 (unsigned int)nPFrames, (unsigned int)nIDRPeriod); 4874 4875 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) { 4876 DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!"); 4877 return false; 4878 } 4879 4880 if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) { 4881 DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed"); 4882 return false; 4883 } 4884 4885 if (!intra_period.num_bframes) 4886 intra_period.num_pframes = nPFrames; 4887 control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; 4888 control.value = nIDRPeriod; 4889 4890 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4891 4892 if (rc) { 4893 DEBUG_PRINT_ERROR("Failed to set control"); 4894 return false; 4895 } 4896 4897 idrperiod.idrperiod = nIDRPeriod; 4898 return true; 4899 } 4900 4901 bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) 4902 { 4903 int rc = 0; 4904 struct v4l2_control control; 4905 4906 DEBUG_PRINT_LOW("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level); 4907 4908 if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) && 4909 (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)) { 4910 4911 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC; 4912 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 4913 4914 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4915 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4916 4917 if (rc) { 4918 DEBUG_PRINT_ERROR("Failed to set control"); 4919 return false; 4920 } 4921 4922 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4923 entropy.longentropysel = control.value; 4924 4925 if (i_cabac_level == 0) { 4926 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0; 4927 } else if (i_cabac_level == 1) { 4928 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1; 4929 } else if (i_cabac_level == 2) { 4930 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2; 4931 } 4932 4933 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL; 4934 //control.value = entropy_cfg.cabacmodel; 4935 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4936 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4937 4938 if (rc) { 4939 DEBUG_PRINT_ERROR("Failed to set control"); 4940 return false; 4941 } 4942 4943 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4944 entropy.cabacmodel=control.value; 4945 } else if (!enable) { 4946 control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; 4947 control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; 4948 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4949 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4950 4951 if (rc) { 4952 DEBUG_PRINT_ERROR("Failed to set control"); 4953 return false; 4954 } 4955 4956 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4957 entropy.longentropysel=control.value; 4958 } else { 4959 DEBUG_PRINT_ERROR("Invalid Entropy mode for Baseline Profile"); 4960 return false; 4961 } 4962 4963 return true; 4964 } 4965 4966 bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB 4967 { 4968 int rc; 4969 struct v4l2_control control; 4970 bool status = true; 4971 4972 if ((Codec != OMX_IndexParamVideoH263) && (nSlicesize)) { 4973 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB; 4974 } else { 4975 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; 4976 } 4977 4978 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 4979 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 4980 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4981 4982 if (rc) { 4983 DEBUG_PRINT_ERROR("Failed to set control"); 4984 return false; 4985 } 4986 4987 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 4988 multislice.mslice_mode=control.value; 4989 4990 if (multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) { 4991 4992 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; 4993 control.value = nSlicesize; 4994 DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d", control.id, control.value); 4995 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 4996 4997 if (rc) { 4998 DEBUG_PRINT_ERROR("Failed to set control"); 4999 return false; 5000 } 5001 5002 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5003 multislice.mslice_size=control.value; 5004 5005 } 5006 5007 return status; 5008 } 5009 5010 bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) 5011 { 5012 bool status = true; 5013 int rc; 5014 struct v4l2_control control_mode,control_mbs; 5015 control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE; 5016 5017 // There is no disabled mode. Disabled mode is indicated by a 0 count. 5018 if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) { 5019 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE; 5020 return status; 5021 } else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && 5022 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 5023 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC; 5024 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS; 5025 control_mbs.value=irMBs; 5026 } else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) && 5027 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 5028 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE; 5029 control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS; 5030 control_mbs.value=irMBs; 5031 } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) && 5032 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 5033 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE; 5034 } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) && 5035 (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) { 5036 control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM; 5037 control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS; 5038 control_mbs.value = irMBs; 5039 } else { 5040 DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:" 5041 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode); 5042 return false; 5043 } 5044 5045 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", control_mode.id, control_mode.value); 5046 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode); 5047 5048 if (rc) { 5049 DEBUG_PRINT_ERROR("Failed to set control"); 5050 return false; 5051 } 5052 5053 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value); 5054 5055 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control_mbs.id, control_mbs.value); 5056 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs); 5057 5058 if (rc) { 5059 DEBUG_PRINT_ERROR("Failed to set control"); 5060 return false; 5061 } 5062 5063 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mbs.id, control_mbs.value); 5064 5065 intra_refresh.irmode = control_mode.value; 5066 intra_refresh.mbcount = control_mbs.value; 5067 5068 return status; 5069 } 5070 5071 bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) 5072 { 5073 bool status = true; 5074 struct venc_headerextension hec_cfg; 5075 struct venc_multiclicecfg multislice_cfg; 5076 int rc; 5077 OMX_U32 resynchMarkerSpacingBytes = 0; 5078 struct v4l2_control control; 5079 5080 memset(&control, 0, sizeof(control)); 5081 5082 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 5083 if (error_resilience->bEnableHEC) { 5084 hec_cfg.header_extension = 1; 5085 } else { 5086 hec_cfg.header_extension = 0; 5087 } 5088 5089 hec.header_extension = error_resilience->bEnableHEC; 5090 } 5091 5092 if (error_resilience->bEnableRVLC) { 5093 DEBUG_PRINT_ERROR("RVLC is not Supported"); 5094 return false; 5095 } 5096 5097 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && 5098 (error_resilience->bEnableDataPartitioning)) { 5099 DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264"); 5100 return false; 5101 } 5102 5103 if (error_resilience->nResynchMarkerSpacing) { 5104 resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing; 5105 resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3; 5106 } 5107 if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && 5108 (error_resilience->nResynchMarkerSpacing)) { 5109 multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; 5110 multislice_cfg.mslice_size = resynchMarkerSpacingBytes; 5111 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 5112 control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES; 5113 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 && 5114 error_resilience->bEnableDataPartitioning) { 5115 multislice_cfg.mslice_mode = VEN_MSLICE_GOB; 5116 multislice_cfg.mslice_size = resynchMarkerSpacingBytes; 5117 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 5118 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB; 5119 } else { 5120 multislice_cfg.mslice_mode = VEN_MSLICE_OFF; 5121 multislice_cfg.mslice_size = 0; 5122 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; 5123 control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; 5124 } 5125 5126 DEBUG_PRINT_LOW("%s(): mode = %lu, size = %lu", __func__, 5127 multislice_cfg.mslice_mode, multislice_cfg.mslice_size); 5128 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 5129 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5130 5131 if (rc) { 5132 DEBUG_PRINT_ERROR("Failed to set Slice mode control"); 5133 return false; 5134 } 5135 5136 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 5137 multislice.mslice_mode=control.value; 5138 5139 control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; 5140 control.value = resynchMarkerSpacingBytes; 5141 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 5142 5143 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5144 5145 if (rc) { 5146 DEBUG_PRINT_ERROR("Failed to set MAX MB control"); 5147 return false; 5148 } 5149 5150 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 5151 multislice.mslice_mode = multislice_cfg.mslice_mode; 5152 multislice.mslice_size = multislice_cfg.mslice_size; 5153 return status; 5154 } 5155 5156 bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) 5157 { 5158 int rc; 5159 struct v4l2_control control; 5160 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE; 5161 5162 if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable) { 5163 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED; 5164 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisable) { 5165 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED; 5166 } else if (loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary) { 5167 control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY; 5168 } 5169 5170 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 5171 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5172 5173 if (rc) { 5174 return false; 5175 } 5176 5177 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5178 5179 dbkfilter.db_mode=control.value; 5180 5181 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA; 5182 control.value=0; 5183 5184 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 5185 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5186 5187 if (rc) { 5188 return false; 5189 } 5190 5191 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5192 control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA; 5193 control.value=0; 5194 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 5195 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5196 5197 if (rc) { 5198 return false; 5199 } 5200 5201 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5202 5203 5204 dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; 5205 return true; 5206 } 5207 5208 bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) 5209 { 5210 DEBUG_PRINT_LOW("venc_set_target_bitrate: bitrate = %u", 5211 (unsigned int)nTargetBitrate); 5212 struct v4l2_control control; 5213 int rc = 0; 5214 control.id = V4L2_CID_MPEG_VIDEO_BITRATE; 5215 control.value = nTargetBitrate; 5216 5217 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 5218 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5219 5220 if (rc) { 5221 DEBUG_PRINT_ERROR("Failed to set control"); 5222 return false; 5223 } 5224 5225 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5226 5227 5228 m_sVenc_cfg.targetbitrate = control.value; 5229 bitrate.target_bitrate = control.value; 5230 5231 if (!config) { 5232 m_level_set = false; 5233 5234 if (venc_set_profile_level(0, 0)) { 5235 DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu",profile_level.level); 5236 } 5237 } 5238 5239 // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution 5240 // has been specified 5241 if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) { 5242 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0}, 5243 numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; 5244 5245 DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate"); 5246 for (OMX_U32 i = 0; i < numLayers; ++i) { 5247 layerBitrates[i] = 5248 (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100; 5249 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)", 5250 i, temporal_layers_config.nTemporalLayerBitrateFraction[i], 5251 layerBitrates[i], bitrate.target_bitrate); 5252 } 5253 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) { 5254 return false; 5255 } 5256 } 5257 5258 return true; 5259 } 5260 5261 bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) 5262 { 5263 struct v4l2_streamparm parm; 5264 int rc = 0; 5265 struct venc_framerate frame_rate_cfg; 5266 Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); 5267 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5268 parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator; 5269 parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator; 5270 5271 if (frame_rate_cfg.fps_numerator > 0) 5272 rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm); 5273 5274 if (rc) { 5275 DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed"); 5276 return false; 5277 } 5278 5279 m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; 5280 m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; 5281 5282 if (!config) { 5283 m_level_set = false; 5284 5285 if (venc_set_profile_level(0, 0)) { 5286 DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu",profile_level.level); 5287 } 5288 } 5289 5290 return true; 5291 } 5292 5293 bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) 5294 { 5295 struct v4l2_format fmt; 5296 int color_space = 0; 5297 DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format); 5298 5299 switch ((int)color_format) { 5300 case OMX_COLOR_FormatYUV420SemiPlanar: 5301 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m: 5302 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; 5303 color_space = V4L2_COLORSPACE_470_SYSTEM_BG; 5304 break; 5305 case QOMX_COLOR_FormatYVU420SemiPlanar: 5306 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21; 5307 color_space = V4L2_COLORSPACE_470_SYSTEM_BG; 5308 break; 5309 case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed: 5310 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC; 5311 color_space = V4L2_COLORSPACE_470_SYSTEM_BG; 5312 break; 5313 case QOMX_COLOR_Format32bitRGBA8888: 5314 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32; 5315 break; 5316 case QOMX_COLOR_Format32bitRGBA8888Compressed: 5317 m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC; 5318 break; 5319 default: 5320 DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format); 5321 m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT; 5322 color_space = V4L2_COLORSPACE_470_SYSTEM_BG; 5323 DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set"); 5324 break; 5325 } 5326 5327 memset(&fmt, 0, sizeof(fmt)); 5328 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5329 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; 5330 fmt.fmt.pix_mp.colorspace = color_space; 5331 fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; 5332 fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; 5333 5334 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 5335 DEBUG_PRINT_ERROR("Failed setting color format %x", color_format); 5336 return false; 5337 } 5338 5339 return true; 5340 } 5341 5342 bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) 5343 { 5344 DEBUG_PRINT_LOW("venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); 5345 5346 if (intra_vop_refresh == OMX_TRUE) { 5347 struct v4l2_control control; 5348 int rc; 5349 control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME; 5350 control.value = 1; 5351 DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 5352 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5353 5354 if (rc) { 5355 DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control"); 5356 return false; 5357 } 5358 5359 DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 5360 } else { 5361 DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect"); 5362 } 5363 5364 return true; 5365 } 5366 5367 bool venc_dev::venc_set_deinterlace(OMX_U32 enable) 5368 { 5369 DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable); 5370 struct v4l2_control control; 5371 int rc; 5372 control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE; 5373 if (enable) 5374 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED; 5375 else 5376 control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED; 5377 5378 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 5379 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5380 if (rc) { 5381 DEBUG_PRINT_ERROR("Failed to set Deinterlcing control"); 5382 return false; 5383 } 5384 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 5385 deinterlace_enabled = true; 5386 return true; 5387 } 5388 5389 bool venc_dev::venc_calibrate_gop() 5390 { 5391 int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers; 5392 int num_sub_gops_in_a_gop; 5393 nPframes = intra_period.num_pframes; 5394 nBframes = intra_period.num_bframes; 5395 nLayers = hier_layers.numlayers; 5396 if (temporal_layers_config.nPLayers) { 5397 nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; 5398 } 5399 5400 if (!nPframes && nLayers) { 5401 DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n"); 5402 return false; 5403 } 5404 5405 if (nLayers > 1) { /*Multi-layer encoding*/ 5406 sub_gop_size = 1 << (nLayers - 1); 5407 /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of 5408 * below calculations we are ignoring +1 . Ignoring +1 in below 5409 * calculations is not a mistake but intentional. 5410 */ 5411 gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size)); 5412 num_sub_gops_in_a_gop = gop_size/sub_gop_size; 5413 if (nBframes) { /*Hier-B case*/ 5414 /* 5415 * Frame Type--> I B B B P B B B P I B B P ... 5416 * Layer --> 0 2 1 2 0 2 1 2 0 0 2 1 2 ... 5417 * nPframes = 2, nBframes = 6, nLayers = 3 5418 * 5419 * Intention is to keep the intraperiod as close as possible to what is desired 5420 * by the client while adjusting nPframes and nBframes to meet other constraints. 5421 * eg1: Input by client: nPframes = 9, nBframes = 14, nLayers = 2 5422 * Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2 5423 * 5424 * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2 5425 * Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2 5426 */ 5427 nPframes = num_sub_gops_in_a_gop; 5428 nBframes = gop_size - nPframes; 5429 } else { /*Hier-P case*/ 5430 /* 5431 * Frame Type--> I P P P P P P P I P P P P ... 5432 * Layer--> 0 2 1 2 0 2 1 2 0 2 1 2 0 ... 5433 * nPframes = 7, nBframes = 0, nLayers = 3 5434 * 5435 * Intention is to keep the intraperiod as close as possible to what is desired 5436 * by the client while adjusting nPframes and nBframes to meet other constraints. 5437 * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3 5438 * Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3 5439 * 5440 * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3 5441 * Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3 5442 */ 5443 nPframes = gop_size - 1; 5444 } 5445 } else { /*Single-layer encoding*/ 5446 if (nBframes) { 5447 /* I P B B B P B B B P B B B I P B B... 5448 * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17... 5449 * nPframes = 3, nBframes = 9, nLayers = 0 5450 * 5451 * ratio is rounded, 5452 * eg1: nPframes = 9, nBframes = 11 => ratio = 1 5453 * eg2: nPframes = 9, nBframes = 16 => ratio = 2 5454 */ 5455 ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3)); 5456 nBframes = ratio * nPframes; 5457 } 5458 } 5459 DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d", 5460 intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes); 5461 intra_period.num_pframes = nPframes; 5462 intra_period.num_bframes = nBframes; 5463 hier_layers.numlayers = nLayers; 5464 return true; 5465 } 5466 5467 bool venc_dev::venc_set_bitrate_type(OMX_U32 type) 5468 { 5469 struct v4l2_control control; 5470 int rc = 0; 5471 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE; 5472 control.value = type; 5473 DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type); 5474 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5475 if (rc) { 5476 DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed", 5477 bitrate_type_string(type)); 5478 return false; 5479 } 5480 return true; 5481 } 5482 5483 bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers) 5484 { 5485 DEBUG_PRINT_LOW("venc_set_layer_bitrates"); 5486 struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS]; 5487 struct v4l2_ext_controls controls; 5488 int rc = 0; 5489 OMX_U32 i; 5490 5491 if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) { 5492 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc); 5493 return false; 5494 } 5495 5496 for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) { 5497 if (!layerBitrate[i]) { 5498 DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i); 5499 return false; 5500 } else { 5501 ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE; 5502 ctrl[i].value = layerBitrate[i]; 5503 } 5504 } 5505 controls.count = numLayers; 5506 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 5507 controls.controls = ctrl; 5508 5509 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 5510 if (rc) { 5511 DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc); 5512 return false; 5513 } 5514 5515 DEBUG_PRINT_LOW("Layerwise bitrate configured successfully"); 5516 return true; 5517 } 5518 5519 bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp) 5520 { 5521 DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers"); 5522 struct v4l2_control control; 5523 int rc; 5524 5525 if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) { 5526 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes"); 5527 return false; 5528 } 5529 5530 if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) { 5531 DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers); 5532 return false; 5533 } 5534 if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) { 5535 DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval); 5536 return false; 5537 } 5538 5539 hier_layers.numlayers = hhp->nHpLayers; 5540 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 5541 hier_layers.hier_mode = HIER_P_HYBRID; 5542 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 5543 hier_layers.hier_mode = HIER_P; 5544 } 5545 if (venc_calibrate_gop()) { 5546 // Update the driver with the new nPframes and nBframes 5547 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; 5548 control.value = intra_period.num_pframes; 5549 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5550 if (rc) { 5551 DEBUG_PRINT_ERROR("Failed to set control"); 5552 return false; 5553 } 5554 5555 control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; 5556 control.value = intra_period.num_bframes; 5557 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5558 if (rc) { 5559 DEBUG_PRINT_ERROR("Failed to set control"); 5560 return false; 5561 } 5562 DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)", 5563 intra_period.num_pframes, intra_period.num_bframes); 5564 } else { 5565 DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes"); 5566 return false; 5567 } 5568 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 5569 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE; 5570 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 5571 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS; 5572 } 5573 control.value = hhp->nHpLayers - 1; 5574 5575 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", 5576 control.id, control.value); 5577 5578 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5579 if (rc) { 5580 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc); 5581 return false; 5582 } 5583 5584 DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d", 5585 control.id, control.value); 5586 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 5587 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC; 5588 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED; 5589 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 5590 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL"); 5591 return false; 5592 } 5593 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 5594 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS; 5595 control.value = hhp->nHpLayers - 1; 5596 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 5597 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL"); 5598 return false; 5599 } 5600 } else { 5601 DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype); 5602 return false; 5603 } 5604 5605 if(venc_set_session_qp_range (hhp->nMinQuantizer, 5606 hhp->nMaxQuantizer) == false) { 5607 DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed", 5608 (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer); 5609 return false; 5610 } else { 5611 session_qp_values.minqp = hhp->nMinQuantizer; 5612 session_qp_values.maxqp = hhp->nMaxQuantizer; 5613 } 5614 5615 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0}; 5616 for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) { 5617 layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i]; 5618 hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i]; 5619 DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]); 5620 } 5621 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) { 5622 DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d", 5623 hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1], 5624 hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3], 5625 hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]); 5626 return false; 5627 } 5628 hybrid_hp.nHpLayers = hhp->nHpLayers; 5629 5630 // Set this or else the layer0 bitrate will be overwritten by 5631 // default value in component 5632 m_sVenc_cfg.targetbitrate = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0]; 5633 hybrid_hp.nHpLayers = hhp->nHpLayers; 5634 hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval; 5635 hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer; 5636 hybrid_hp.nMinQuantizer = hhp->nMinQuantizer; 5637 return true; 5638 } 5639 5640 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count) 5641 { 5642 DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable); 5643 struct v4l2_ext_control ctrl[2]; 5644 struct v4l2_ext_controls controls; 5645 int rc; 5646 5647 if (!venc_validate_hybridhp_params(0, 0, count, 0)) { 5648 DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP"); 5649 return false; 5650 } 5651 5652 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE; 5653 if (enable) 5654 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL; 5655 else 5656 ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE; 5657 5658 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT; 5659 if (enable && count > 0) 5660 ctrl[1].value = count; 5661 else if (enable) 5662 ctrl[1].value = 1; 5663 else 5664 ctrl[1].value = 0; 5665 5666 controls.count = 2; 5667 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 5668 controls.controls = ctrl; 5669 5670 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d", 5671 controls.controls[0].id, controls.controls[0].value, 5672 controls.controls[1].id, controls.controls[1].value); 5673 5674 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 5675 if (rc) { 5676 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc); 5677 return false; 5678 } 5679 ltrinfo.enabled = enable; 5680 ltrinfo.count = count; 5681 5682 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d", 5683 controls.controls[0].id, controls.controls[0].value, 5684 controls.controls[1].id, controls.controls[1].value); 5685 5686 if (!venc_set_profile_level(0, 0)) { 5687 DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET", 5688 __func__); 5689 } else { 5690 DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET", 5691 __func__, codec_profile.profile, profile_level.level); 5692 } 5693 5694 return true; 5695 } 5696 5697 bool venc_dev::venc_set_useltr(OMX_U32 frameIdx) 5698 { 5699 DEBUG_PRINT_LOW("venc_use_goldenframe"); 5700 int rc = true; 5701 struct v4l2_control control; 5702 5703 control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME; 5704 control.value = frameIdx; 5705 5706 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5707 if (rc) { 5708 DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc); 5709 return false; 5710 } 5711 5712 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d", 5713 control.id, control.value); 5714 return true; 5715 } 5716 5717 bool venc_dev::venc_set_markltr(OMX_U32 frameIdx) 5718 { 5719 DEBUG_PRINT_LOW("venc_set_goldenframe"); 5720 int rc = true; 5721 struct v4l2_control control; 5722 5723 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME; 5724 control.value = frameIdx; 5725 5726 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5727 if (rc) { 5728 DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc); 5729 return false; 5730 } 5731 5732 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d", 5733 control.id, control.value); 5734 return true; 5735 } 5736 5737 bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle) 5738 { 5739 DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle); 5740 struct v4l2_control control; 5741 int rc; 5742 struct v4l2_format fmt; 5743 struct v4l2_requestbuffers bufreq; 5744 5745 control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION; 5746 if (rotation_angle == 0) 5747 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE; 5748 else if (rotation_angle == 90) 5749 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90; 5750 else if (rotation_angle == 180) 5751 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180; 5752 else if (rotation_angle == 270) 5753 control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270; 5754 else { 5755 DEBUG_PRINT_ERROR("Failed to find valid rotation angle"); 5756 return false; 5757 } 5758 5759 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 5760 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5761 if (rc) { 5762 DEBUG_PRINT_HIGH("Failed to set VPE Rotation control"); 5763 return false; 5764 } 5765 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 5766 5767 memset(&fmt, 0, sizeof(fmt)); 5768 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5769 fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height; 5770 fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width; 5771 fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; 5772 if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { 5773 DEBUG_PRINT_ERROR("Failed to set format on capture port"); 5774 return false; 5775 } 5776 5777 m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; 5778 bufreq.memory = V4L2_MEMORY_USERPTR; 5779 bufreq.count = m_sOutput_buff_property.actualcount; 5780 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 5781 if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { 5782 DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation"); 5783 return false; 5784 } 5785 if (bufreq.count >= m_sOutput_buff_property.mincount) 5786 m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count; 5787 5788 return true; 5789 } 5790 5791 bool venc_dev::venc_set_searchrange() 5792 { 5793 DEBUG_PRINT_LOW("venc_set_searchrange"); 5794 struct v4l2_control control; 5795 struct v4l2_ext_control ctrl[6]; 5796 struct v4l2_ext_controls controls; 5797 int rc; 5798 5799 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 5800 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE; 5801 ctrl[0].value = 16; 5802 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE; 5803 ctrl[1].value = 4; 5804 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE; 5805 ctrl[2].value = 16; 5806 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE; 5807 ctrl[3].value = 4; 5808 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE; 5809 ctrl[4].value = 12; 5810 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE; 5811 ctrl[5].value = 4; 5812 } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) || 5813 (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) { 5814 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE; 5815 ctrl[0].value = 16; 5816 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE; 5817 ctrl[1].value = 4; 5818 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE; 5819 ctrl[2].value = 16; 5820 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE; 5821 ctrl[3].value = 4; 5822 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE; 5823 ctrl[4].value = 12; 5824 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE; 5825 ctrl[5].value = 4; 5826 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 5827 ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE; 5828 ctrl[0].value = 4; 5829 ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE; 5830 ctrl[1].value = 4; 5831 ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE; 5832 ctrl[2].value = 4; 5833 ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE; 5834 ctrl[3].value = 4; 5835 ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE; 5836 ctrl[4].value = 4; 5837 ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE; 5838 ctrl[5].value = 4; 5839 } else { 5840 DEBUG_PRINT_ERROR("Invalid codec type"); 5841 return false; 5842 } 5843 controls.count = 6; 5844 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 5845 controls.controls = ctrl; 5846 5847 DEBUG_PRINT_LOW(" Calling IOCTL set control for" 5848 "id=%x, val=%d id=%x, val=%d" 5849 "id=%x, val=%d id=%x, val=%d" 5850 "id=%x, val=%d id=%x, val=%d", 5851 controls.controls[0].id, controls.controls[0].value, 5852 controls.controls[1].id, controls.controls[1].value, 5853 controls.controls[2].id, controls.controls[2].value, 5854 controls.controls[3].id, controls.controls[3].value, 5855 controls.controls[4].id, controls.controls[4].value, 5856 controls.controls[5].id, controls.controls[5].value); 5857 5858 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 5859 if (rc) { 5860 DEBUG_PRINT_ERROR("Failed to set search range %d", rc); 5861 return false; 5862 } 5863 return true; 5864 } 5865 5866 bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) 5867 { 5868 bool status = true; 5869 struct v4l2_control control; 5870 int rc = 0; 5871 control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL; 5872 5873 switch (eControlRate) { 5874 case OMX_Video_ControlRateDisable: 5875 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF; 5876 break; 5877 case OMX_Video_ControlRateVariableSkipFrames: 5878 (supported_rc_modes & RC_VBR_VFR) ? 5879 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR : 5880 status = false; 5881 break; 5882 case OMX_Video_ControlRateVariable: 5883 (supported_rc_modes & RC_VBR_CFR) ? 5884 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR : 5885 status = false; 5886 break; 5887 case OMX_Video_ControlRateConstantSkipFrames: 5888 (supported_rc_modes & RC_CBR_VFR) ? 5889 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR : 5890 status = false; 5891 break; 5892 case OMX_Video_ControlRateConstant: 5893 (supported_rc_modes & RC_CBR_CFR) ? 5894 control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR : 5895 status = false; 5896 break; 5897 default: 5898 status = false; 5899 break; 5900 } 5901 5902 if (status) { 5903 5904 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 5905 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5906 5907 if (rc) { 5908 DEBUG_PRINT_ERROR("Failed to set control"); 5909 return false; 5910 } 5911 5912 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5913 5914 rate_ctrl.rcmode = control.value; 5915 } 5916 5917 #ifdef _VQZIP_ 5918 if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR) 5919 && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 5920 /* Enable VQZIP SEI by default for camcorder RC modes */ 5921 5922 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI; 5923 control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE; 5924 DEBUG_PRINT_HIGH("Set VQZIP SEI:"); 5925 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) { 5926 DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed"); 5927 } 5928 } 5929 #endif //_VQZIP_ 5930 5931 return status; 5932 } 5933 5934 bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel) 5935 { 5936 bool status = true; 5937 struct v4l2_control control; 5938 int rc = 0; 5939 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL; 5940 5941 switch (ePerfLevel) { 5942 case OMX_QCOM_PerfLevelNominal: 5943 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL; 5944 break; 5945 case OMX_QCOM_PerfLevelTurbo: 5946 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO; 5947 break; 5948 default: 5949 status = false; 5950 break; 5951 } 5952 5953 if (status) { 5954 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 5955 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 5956 5957 if (rc) { 5958 DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value); 5959 return false; 5960 } 5961 5962 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 5963 } 5964 return status; 5965 } 5966 5967 bool venc_dev::venc_set_perf_mode(OMX_U32 mode) 5968 { 5969 struct v4l2_control control; 5970 if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) { 5971 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE; 5972 control.value = mode; 5973 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE"); 5974 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 5975 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE"); 5976 return false; 5977 } 5978 return true; 5979 } else { 5980 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode); 5981 return false; 5982 } 5983 } 5984 5985 bool venc_dev::venc_set_qp(OMX_U32 nQp) 5986 { 5987 struct v4l2_control control; 5988 if (nQp) { 5989 control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP; 5990 control.value = nQp; 5991 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP"); 5992 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 5993 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP"); 5994 return false; 5995 } 5996 } else { 5997 DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp); 5998 return false; 5999 } 6000 return true; 6001 } 6002 6003 bool venc_dev::venc_set_aspectratio(void *nSar) 6004 { 6005 int rc; 6006 struct v4l2_control control; 6007 struct v4l2_ext_control ctrl[2]; 6008 struct v4l2_ext_controls controls; 6009 QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar; 6010 6011 sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar; 6012 6013 ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH; 6014 ctrl[0].value = sar->nSARWidth; 6015 ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT; 6016 ctrl[1].value = sar->nSARHeight; 6017 6018 controls.count = 2; 6019 controls.ctrl_class = V4L2_CTRL_CLASS_MPEG; 6020 controls.controls = ctrl; 6021 6022 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d", 6023 controls.controls[0].id, controls.controls[0].value, 6024 controls.controls[1].id, controls.controls[1].value); 6025 6026 rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls); 6027 if (rc) { 6028 DEBUG_PRINT_ERROR("Failed to set SAR %d", rc); 6029 return false; 6030 } 6031 6032 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d", 6033 controls.controls[0].id, controls.controls[0].value, 6034 controls.controls[1].id, controls.controls[1].value); 6035 return true; 6036 } 6037 6038 bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers) 6039 { 6040 struct v4l2_control control; 6041 if (hierp_layers && (hier_layers.hier_mode == HIER_P) && 6042 (hierp_layers <= hier_layers.numlayers)) { 6043 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS; 6044 control.value = hierp_layers - 1; 6045 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS"); 6046 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6047 DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS"); 6048 return false; 6049 } 6050 return true; 6051 } else { 6052 DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d", 6053 hierp_layers); 6054 return false; 6055 } 6056 } 6057 6058 bool venc_dev::venc_set_baselayerid(OMX_U32 baseid) 6059 { 6060 struct v4l2_control control; 6061 if (hier_layers.hier_mode == HIER_P) { 6062 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID; 6063 control.value = baseid; 6064 DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID"); 6065 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6066 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID"); 6067 return false; 6068 } 6069 return true; 6070 } else { 6071 DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d", 6072 hier_layers.hier_mode); 6073 return false; 6074 } 6075 } 6076 6077 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable) 6078 { 6079 struct v4l2_control control; 6080 int rc = 0; 6081 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO; 6082 6083 if (enable) 6084 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED; 6085 else 6086 control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED; 6087 6088 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value); 6089 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 6090 if (rc) { 6091 DEBUG_PRINT_ERROR("Failed to set VUI timing info control"); 6092 return false; 6093 } 6094 DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value); 6095 return true; 6096 } 6097 6098 bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate) 6099 { 6100 struct v4l2_control control; 6101 int rc = 0; 6102 control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK; 6103 control.value = nPeakBitrate; 6104 6105 DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate); 6106 6107 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 6108 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 6109 6110 if (rc) { 6111 DEBUG_PRINT_ERROR("Failed to set peak bitrate control"); 6112 return false; 6113 } 6114 6115 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 6116 6117 return true; 6118 } 6119 6120 bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable) 6121 { 6122 struct v4l2_control control; 6123 int rc = 0; 6124 control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE; 6125 6126 if (enable) 6127 control.value = 1; 6128 else 6129 control.value = 0; 6130 6131 DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value); 6132 6133 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 6134 6135 rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 6136 if (rc) { 6137 DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience"); 6138 return false; 6139 } 6140 vpx_err_resilience.enable = 1; 6141 DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value); 6142 return true; 6143 } 6144 6145 bool venc_dev::venc_set_priority(OMX_U32 priority) { 6146 struct v4l2_control control; 6147 6148 control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY; 6149 if (priority == 0) 6150 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE; 6151 else 6152 control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE; 6153 6154 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6155 DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s", 6156 priority == 0 ? "ENABLE" : "DISABLE"); 6157 return false; 6158 } 6159 return true; 6160 } 6161 6162 bool venc_dev::venc_set_operatingrate(OMX_U32 rate) { 6163 struct v4l2_control control; 6164 6165 control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE; 6166 control.value = rate; 6167 6168 DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16); 6169 DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value); 6170 6171 if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6172 hw_overload = errno == EBUSY; 6173 DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)", 6174 rate >> 16, hw_overload ? "HW overload" : strerror(errno)); 6175 return false; 6176 } 6177 operating_rate = rate; 6178 DEBUG_PRINT_LOW("Operating Rate Set = %d fps", rate >> 16); 6179 return true; 6180 } 6181 6182 bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) { 6183 char *userptr; 6184 int fd; 6185 unsigned offset; 6186 ssize_t size; 6187 struct msm_vidc_roi_qp_payload *roiData; 6188 if (!roiInfo) { 6189 DEBUG_PRINT_ERROR("No ROI info present"); 6190 return false; 6191 } 6192 if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 && 6193 m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) { 6194 DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype); 6195 return false; 6196 } 6197 6198 venc_roiqp_log_buffers(roiInfo); 6199 mInputExtradata.getForConfig(&userptr, &fd, &offset, &size); 6200 if (!userptr || size < roiInfo->nRoiMBInfoSize) { 6201 DEBUG_PRINT_ERROR("ROI extradata insufficient. Check if OMX_QTIIndexParamVideoEnableRoiInfo was set. (%p, %zd, %u)", userptr, size, roiInfo->nRoiMBInfoSize); 6202 return false; 6203 } 6204 6205 OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)userptr; 6206 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_roi_qp_payload) + roiInfo->nRoiMBInfoSize - 2 * sizeof(unsigned int), 4); 6207 data->nVersion.nVersion = OMX_SPEC_VERSION; 6208 data->nPortIndex = 0; 6209 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP; 6210 data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload); 6211 6212 roiData = (struct msm_vidc_roi_qp_payload *)(data->data); 6213 roiData->upper_qp_offset = roiInfo->nUpperQpOffset; 6214 roiData->lower_qp_offset = roiInfo->nLowerQpOffset; 6215 roiData->b_roi_info = roiInfo->bUseRoiInfo; 6216 roiData->mbi_info_size = roiInfo->nRoiMBInfoSize; 6217 memcpy(roiData->data, roiInfo->pRoiMBInfo, roiInfo->nRoiMBInfoSize); 6218 6219 data = (struct OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); 6220 data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4); 6221 data->nVersion.nVersion = OMX_SPEC_VERSION; 6222 data->nPortIndex = 0; 6223 data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE; 6224 data->nDataSize = 0; 6225 return true; 6226 } 6227 6228 bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers, 6229 OMX_U32 *nMaxBLayers) { 6230 6231 // no B-layers for all cases 6232 temporal_layers_config.nMaxBLayers = 0; 6233 temporal_layers_config.nMaxLayers = 1; 6234 6235 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 6236 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 6237 temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec 6238 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 6239 temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec 6240 } 6241 6242 *nMaxLayers = temporal_layers_config.nMaxLayers; 6243 *nMaxBLayers = temporal_layers_config.nMaxBLayers; 6244 return true; 6245 } 6246 6247 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers( 6248 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) { 6249 6250 if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 6251 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC 6252 || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) { 6253 DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype)); 6254 return OMX_ErrorUnsupportedSetting; 6255 } 6256 6257 if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone && 6258 (pTemporalParams->nBLayerCountActual != 0 || 6259 pTemporalParams->nPLayerCountActual != 1)) { 6260 return OMX_ErrorBadParameter; 6261 } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid || 6262 pTemporalParams->nPLayerCountActual < 1) { 6263 return OMX_ErrorBadParameter; 6264 } 6265 6266 if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) { 6267 DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)", 6268 pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers); 6269 return OMX_ErrorBadParameter; 6270 } else if (pTemporalParams->nPLayerCountActual > 6271 temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) { 6272 DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)", 6273 pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual, 6274 temporal_layers_config.nMaxLayers); 6275 return OMX_ErrorBadParameter; 6276 } 6277 6278 // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder), 6279 // use hybrid-HP for best results 6280 bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264; 6281 bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR; 6282 bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR; 6283 6284 // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid 6285 bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS); 6286 6287 DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP", 6288 rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable"); 6289 6290 if (bUseHybridMode && 6291 !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual, 6292 pTemporalParams->nBLayerCountActual, 6293 0 /* LTR count */, (int) HIER_P_HYBRID)) { 6294 bUseHybridMode = false; 6295 DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP"); 6296 } 6297 6298 if (intra_period.num_bframes) { 6299 DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers"); 6300 return OMX_ErrorUnsupportedSetting; 6301 } 6302 6303 if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) { 6304 DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)", 6305 intra_period.num_pframes, intra_period.num_bframes); 6306 return OMX_ErrorUnsupportedSetting; 6307 } 6308 6309 struct v4l2_control control; 6310 // Num enhancements layers does not include the base-layer 6311 control.value = pTemporalParams->nPLayerCountActual - 1; 6312 6313 if (bUseHybridMode) { 6314 DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value); 6315 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE; 6316 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6317 bUseHybridMode = false; 6318 DEBUG_PRINT_ERROR("Failed to set hybrid HP"); 6319 } else { 6320 // Disable normal HP if Hybrid mode is being enabled 6321 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS; 6322 control.value = 0; 6323 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6324 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value); 6325 return OMX_ErrorUnsupportedSetting; 6326 } 6327 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS; 6328 control.value = 0; 6329 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6330 DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value); 6331 return OMX_ErrorUnsupportedSetting; 6332 } 6333 } 6334 } 6335 6336 if (!bUseHybridMode) { 6337 6338 // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS 6339 if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) { 6340 DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS); 6341 return OMX_ErrorUnsupportedSetting; 6342 } 6343 6344 DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value); 6345 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS; 6346 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6347 DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp"); 6348 return OMX_ErrorUnsupportedSetting; 6349 } 6350 6351 // configure max layers for a session.. Okay to use current num-layers as max 6352 // since we do not plan to support dynamic changes to number of layers 6353 control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS; 6354 control.value = pTemporalParams->nPLayerCountActual - 1; 6355 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6356 DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value); 6357 return OMX_ErrorUnsupportedSetting; 6358 6359 } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) { 6360 // Disable hybrid mode if it was enabled already 6361 DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)"); 6362 control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE; 6363 control.value = 0; 6364 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6365 DEBUG_PRINT_ERROR("Failed to disable hybrid HP !"); 6366 return OMX_ErrorUnsupportedSetting; 6367 } 6368 } 6369 } 6370 6371 // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement.. 6372 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 6373 DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL"); 6374 control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC; 6375 control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED; 6376 if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { 6377 DEBUG_PRINT_ERROR("Failed to enable SVC_NAL"); 6378 return OMX_ErrorUnsupportedSetting; 6379 } 6380 } 6381 6382 temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P; 6383 temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual; 6384 temporal_layers_config.nBLayers = 0; 6385 6386 temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE; 6387 if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) { 6388 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative.."); 6389 return OMX_ErrorNone; 6390 } 6391 DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified"); 6392 6393 OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0}, 6394 numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual; 6395 6396 OMX_U32 i = 0; 6397 for (; i < numLayers; ++i) { 6398 OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1]; 6399 OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio; 6400 if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) { 6401 DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i); 6402 return OMX_ErrorBadParameter; 6403 } else { 6404 layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100; 6405 temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i]; 6406 temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio; 6407 DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)", 6408 i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate); 6409 } 6410 } 6411 6412 temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE; 6413 6414 // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later.. 6415 if (bitrate.target_bitrate > 0) { 6416 if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) { 6417 return OMX_ErrorUnsupportedSetting; 6418 } 6419 } else { 6420 DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set"); 6421 } 6422 6423 return OMX_ErrorNone; 6424 } 6425 6426 OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() { 6427 OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams; 6428 memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE)); 6429 6430 if (!temporal_layers_config.nPLayers) { 6431 return OMX_ErrorNone; 6432 } 6433 pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 6434 pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers; 6435 pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers; 6436 pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid; 6437 pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers; 6438 pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers; 6439 pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid; 6440 if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) { 6441 for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) { 6442 pTemporalParams.nBitrateRatios[i] = 6443 temporal_layers_config.nTemporalLayerBitrateRatio[i]; 6444 } 6445 } 6446 return venc_set_temporal_layers(&pTemporalParams); 6447 } 6448 6449 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) 6450 { 6451 bool status = true; 6452 6453 if (eProfile == NULL || eLevel == NULL) { 6454 return false; 6455 } 6456 6457 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 6458 switch (codec_profile.profile) { 6459 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 6460 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 6461 break; 6462 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 6463 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 6464 break; 6465 default: 6466 *eProfile = OMX_VIDEO_MPEG4ProfileMax; 6467 status = false; 6468 break; 6469 } 6470 6471 if (!status) { 6472 return status; 6473 } 6474 6475 //profile level 6476 switch (profile_level.level) { 6477 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: 6478 *eLevel = OMX_VIDEO_MPEG4Level0; 6479 break; 6480 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: 6481 *eLevel = OMX_VIDEO_MPEG4Level0b; 6482 break; 6483 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: 6484 *eLevel = OMX_VIDEO_MPEG4Level1; 6485 break; 6486 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: 6487 *eLevel = OMX_VIDEO_MPEG4Level2; 6488 break; 6489 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: 6490 *eLevel = OMX_VIDEO_MPEG4Level3; 6491 break; 6492 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: 6493 *eLevel = OMX_VIDEO_MPEG4Level4; 6494 break; 6495 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: 6496 *eLevel = OMX_VIDEO_MPEG4Level5; 6497 break; 6498 default: 6499 *eLevel = OMX_VIDEO_MPEG4LevelMax; 6500 status = false; 6501 break; 6502 } 6503 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 6504 if (codec_profile.profile == VEN_PROFILE_H263_BASELINE) { 6505 *eProfile = OMX_VIDEO_H263ProfileBaseline; 6506 } else { 6507 *eProfile = OMX_VIDEO_H263ProfileMax; 6508 return false; 6509 } 6510 6511 switch (profile_level.level) { 6512 case VEN_LEVEL_H263_10: 6513 *eLevel = OMX_VIDEO_H263Level10; 6514 break; 6515 case VEN_LEVEL_H263_20: 6516 *eLevel = OMX_VIDEO_H263Level20; 6517 break; 6518 case VEN_LEVEL_H263_30: 6519 *eLevel = OMX_VIDEO_H263Level30; 6520 break; 6521 case VEN_LEVEL_H263_40: 6522 *eLevel = OMX_VIDEO_H263Level40; 6523 break; 6524 case VEN_LEVEL_H263_45: 6525 *eLevel = OMX_VIDEO_H263Level45; 6526 break; 6527 case VEN_LEVEL_H263_50: 6528 *eLevel = OMX_VIDEO_H263Level50; 6529 break; 6530 case VEN_LEVEL_H263_60: 6531 *eLevel = OMX_VIDEO_H263Level60; 6532 break; 6533 case VEN_LEVEL_H263_70: 6534 *eLevel = OMX_VIDEO_H263Level70; 6535 break; 6536 default: 6537 *eLevel = OMX_VIDEO_H263LevelMax; 6538 status = false; 6539 break; 6540 } 6541 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 6542 switch (codec_profile.profile) { 6543 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 6544 *eProfile = OMX_VIDEO_AVCProfileBaseline; 6545 break; 6546 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 6547 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 6548 break; 6549 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH: 6550 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh; 6551 break; 6552 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 6553 *eProfile = OMX_VIDEO_AVCProfileMain; 6554 break; 6555 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 6556 *eProfile = OMX_VIDEO_AVCProfileHigh; 6557 break; 6558 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 6559 *eProfile = OMX_VIDEO_AVCProfileExtended; 6560 break; 6561 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 6562 *eProfile = OMX_VIDEO_AVCProfileHigh10; 6563 break; 6564 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 6565 *eProfile = OMX_VIDEO_AVCProfileHigh422; 6566 break; 6567 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 6568 *eProfile = OMX_VIDEO_AVCProfileHigh444; 6569 break; 6570 default: 6571 *eProfile = OMX_VIDEO_AVCProfileMax; 6572 status = false; 6573 break; 6574 } 6575 6576 if (!status) { 6577 return status; 6578 } 6579 6580 switch (profile_level.level) { 6581 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 6582 *eLevel = OMX_VIDEO_AVCLevel1; 6583 break; 6584 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 6585 *eLevel = OMX_VIDEO_AVCLevel1b; 6586 break; 6587 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 6588 *eLevel = OMX_VIDEO_AVCLevel11; 6589 break; 6590 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 6591 *eLevel = OMX_VIDEO_AVCLevel12; 6592 break; 6593 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 6594 *eLevel = OMX_VIDEO_AVCLevel13; 6595 break; 6596 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 6597 *eLevel = OMX_VIDEO_AVCLevel2; 6598 break; 6599 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 6600 *eLevel = OMX_VIDEO_AVCLevel21; 6601 break; 6602 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 6603 *eLevel = OMX_VIDEO_AVCLevel22; 6604 break; 6605 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 6606 *eLevel = OMX_VIDEO_AVCLevel3; 6607 break; 6608 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 6609 *eLevel = OMX_VIDEO_AVCLevel31; 6610 break; 6611 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 6612 *eLevel = OMX_VIDEO_AVCLevel32; 6613 break; 6614 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 6615 *eLevel = OMX_VIDEO_AVCLevel4; 6616 break; 6617 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 6618 *eLevel = OMX_VIDEO_AVCLevel41; 6619 break; 6620 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 6621 *eLevel = OMX_VIDEO_AVCLevel42; 6622 break; 6623 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 6624 *eLevel = OMX_VIDEO_AVCLevel5; 6625 break; 6626 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 6627 *eLevel = OMX_VIDEO_AVCLevel51; 6628 break; 6629 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2: 6630 *eLevel = OMX_VIDEO_AVCLevel52; 6631 break; 6632 default : 6633 *eLevel = OMX_VIDEO_AVCLevelMax; 6634 status = false; 6635 break; 6636 } 6637 } 6638 else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 6639 switch (codec_profile.profile) { 6640 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: 6641 *eProfile = OMX_VIDEO_VP8ProfileMain; 6642 break; 6643 default: 6644 *eProfile = OMX_VIDEO_VP8ProfileMax; 6645 status = false; 6646 break; 6647 } 6648 if (!status) { 6649 return status; 6650 } 6651 6652 switch (profile_level.level) { 6653 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: 6654 *eLevel = OMX_VIDEO_VP8Level_Version0; 6655 break; 6656 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: 6657 *eLevel = OMX_VIDEO_VP8Level_Version1; 6658 break; 6659 default: 6660 *eLevel = OMX_VIDEO_VP8LevelMax; 6661 status = false; 6662 break; 6663 } 6664 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 6665 switch (codec_profile.profile) { 6666 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN: 6667 *eProfile = OMX_VIDEO_HEVCProfileMain; 6668 break; 6669 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10: 6670 *eProfile = OMX_VIDEO_HEVCProfileMain10; 6671 break; 6672 default: 6673 *eProfile = OMX_VIDEO_HEVCProfileMax; 6674 status = false; 6675 break; 6676 } 6677 if (!status) { 6678 return status; 6679 } 6680 6681 switch (profile_level.level) { 6682 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1: 6683 *eLevel = OMX_VIDEO_HEVCMainTierLevel1; 6684 break; 6685 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1: 6686 *eLevel = OMX_VIDEO_HEVCHighTierLevel1; 6687 break; 6688 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2: 6689 *eLevel = OMX_VIDEO_HEVCMainTierLevel2; 6690 break; 6691 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2: 6692 *eLevel = OMX_VIDEO_HEVCHighTierLevel2; 6693 break; 6694 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1: 6695 *eLevel = OMX_VIDEO_HEVCMainTierLevel21; 6696 break; 6697 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1: 6698 *eLevel = OMX_VIDEO_HEVCHighTierLevel21; 6699 break; 6700 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3: 6701 *eLevel = OMX_VIDEO_HEVCMainTierLevel3; 6702 break; 6703 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3: 6704 *eLevel = OMX_VIDEO_HEVCHighTierLevel3; 6705 break; 6706 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1: 6707 *eLevel = OMX_VIDEO_HEVCMainTierLevel31; 6708 break; 6709 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1: 6710 *eLevel = OMX_VIDEO_HEVCHighTierLevel31; 6711 break; 6712 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4: 6713 *eLevel = OMX_VIDEO_HEVCMainTierLevel4; 6714 break; 6715 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4: 6716 *eLevel = OMX_VIDEO_HEVCHighTierLevel4; 6717 break; 6718 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1: 6719 *eLevel = OMX_VIDEO_HEVCMainTierLevel41; 6720 break; 6721 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1: 6722 *eLevel = OMX_VIDEO_HEVCHighTierLevel41; 6723 break; 6724 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5: 6725 *eLevel = OMX_VIDEO_HEVCMainTierLevel5; 6726 break; 6727 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5: 6728 *eLevel = OMX_VIDEO_HEVCHighTierLevel5; 6729 break; 6730 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1: 6731 *eLevel = OMX_VIDEO_HEVCMainTierLevel51; 6732 break; 6733 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1: 6734 *eLevel = OMX_VIDEO_HEVCHighTierLevel51; 6735 break; 6736 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2: 6737 *eLevel = OMX_VIDEO_HEVCMainTierLevel52; 6738 break; 6739 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2: 6740 *eLevel = OMX_VIDEO_HEVCHighTierLevel52; 6741 break; 6742 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6: 6743 *eLevel = OMX_VIDEO_HEVCMainTierLevel6; 6744 break; 6745 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6: 6746 *eLevel = OMX_VIDEO_HEVCHighTierLevel6; 6747 break; 6748 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1: 6749 *eLevel = OMX_VIDEO_HEVCMainTierLevel61; 6750 break; 6751 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1: 6752 *eLevel = OMX_VIDEO_HEVCHighTierLevel61; 6753 break; 6754 case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2: 6755 *eLevel = OMX_VIDEO_HEVCMainTierLevel62; 6756 break; 6757 default: 6758 *eLevel = OMX_VIDEO_HEVCLevelMax; 6759 status = false; 6760 break; 6761 } 6762 } 6763 6764 return status; 6765 } 6766 6767 bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) 6768 { 6769 OMX_U32 new_profile = 0, new_level = 0; 6770 unsigned const int *profile_tbl = NULL; 6771 OMX_U32 mb_per_frame, mb_per_sec; 6772 bool profile_level_found = false; 6773 6774 DEBUG_PRINT_LOW("Init profile table for respective codec"); 6775 6776 //validate the ht,width,fps,bitrate and set the appropriate profile and level 6777 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { 6778 if (*eProfile == 0) { 6779 if (!m_profile_set) { 6780 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 6781 } else { 6782 switch (codec_profile.profile) { 6783 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 6784 *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 6785 break; 6786 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 6787 *eProfile = OMX_VIDEO_MPEG4ProfileSimple; 6788 break; 6789 default: 6790 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 6791 return false; 6792 } 6793 } 6794 } 6795 6796 if (*eLevel == 0 && !m_level_set) { 6797 *eLevel = OMX_VIDEO_MPEG4LevelMax; 6798 } 6799 6800 if (*eProfile == OMX_VIDEO_MPEG4ProfileSimple) { 6801 profile_tbl = (unsigned int const *)mpeg4_profile_level_table; 6802 } else if (*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) { 6803 profile_tbl = (unsigned int const *) 6804 (&mpeg4_profile_level_table[MPEG4_ASP_START]); 6805 } else { 6806 DEBUG_PRINT_LOW("Unsupported MPEG4 profile type %u", (unsigned int)*eProfile); 6807 return false; 6808 } 6809 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { 6810 if (*eProfile == 0) { 6811 if (!m_profile_set) { 6812 *eProfile = OMX_VIDEO_AVCProfileBaseline; 6813 } else { 6814 switch (codec_profile.profile) { 6815 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 6816 *eProfile = OMX_VIDEO_AVCProfileBaseline; 6817 break; 6818 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 6819 *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 6820 break; 6821 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH: 6822 *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh; 6823 break; 6824 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 6825 *eProfile = OMX_VIDEO_AVCProfileMain; 6826 break; 6827 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 6828 *eProfile = OMX_VIDEO_AVCProfileExtended; 6829 break; 6830 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 6831 *eProfile = OMX_VIDEO_AVCProfileHigh; 6832 break; 6833 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: 6834 *eProfile = OMX_VIDEO_AVCProfileHigh10; 6835 break; 6836 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: 6837 *eProfile = OMX_VIDEO_AVCProfileHigh422; 6838 break; 6839 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: 6840 *eProfile = OMX_VIDEO_AVCProfileHigh444; 6841 break; 6842 default: 6843 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 6844 return false; 6845 } 6846 } 6847 } 6848 6849 if (*eLevel == 0 && !m_level_set) { 6850 *eLevel = OMX_VIDEO_AVCLevelMax; 6851 } 6852 6853 if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) || 6854 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) { 6855 profile_tbl = (unsigned int const *)h264_profile_level_table; 6856 } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) || 6857 (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) { 6858 profile_tbl = (unsigned int const *) 6859 (&h264_profile_level_table[H264_HP_START]); 6860 } else if (*eProfile == OMX_VIDEO_AVCProfileMain) { 6861 profile_tbl = (unsigned int const *) 6862 (&h264_profile_level_table[H264_MP_START]); 6863 } else { 6864 DEBUG_PRINT_LOW("Unsupported AVC profile type %u", (unsigned int)*eProfile); 6865 return false; 6866 } 6867 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { 6868 if (*eProfile == 0) { 6869 if (!m_profile_set) { 6870 *eProfile = OMX_VIDEO_H263ProfileBaseline; 6871 } else { 6872 switch (codec_profile.profile) { 6873 case VEN_PROFILE_H263_BASELINE: 6874 *eProfile = OMX_VIDEO_H263ProfileBaseline; 6875 break; 6876 default: 6877 DEBUG_PRINT_LOW("%s(): Unknown Error", __func__); 6878 return false; 6879 } 6880 } 6881 } 6882 6883 if (*eLevel == 0 && !m_level_set) { 6884 *eLevel = OMX_VIDEO_H263LevelMax; 6885 } 6886 6887 if (*eProfile == OMX_VIDEO_H263ProfileBaseline) { 6888 profile_tbl = (unsigned int const *)h263_profile_level_table; 6889 } else { 6890 DEBUG_PRINT_LOW("Unsupported H.263 profile type %u", (unsigned int)*eProfile); 6891 return false; 6892 } 6893 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { 6894 if (*eProfile == 0) { 6895 *eProfile = OMX_VIDEO_VP8ProfileMain; 6896 } else { 6897 switch (codec_profile.profile) { 6898 case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED: 6899 *eProfile = OMX_VIDEO_VP8ProfileMain; 6900 break; 6901 default: 6902 DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__); 6903 return false; 6904 } 6905 } 6906 if (*eLevel == 0) { 6907 switch (profile_level.level) { 6908 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0: 6909 *eLevel = OMX_VIDEO_VP8Level_Version0; 6910 break; 6911 case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1: 6912 *eLevel = OMX_VIDEO_VP8Level_Version1; 6913 break; 6914 default: 6915 DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__); 6916 return false; 6917 } 6918 } 6919 return true; 6920 } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) { 6921 if (*eProfile == 0) { 6922 if (!m_profile_set) { 6923 *eProfile = OMX_VIDEO_HEVCProfileMain; 6924 } else { 6925 switch (codec_profile.profile) { 6926 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN: 6927 *eProfile = OMX_VIDEO_HEVCProfileMain; 6928 break; 6929 case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10: 6930 *eProfile = OMX_VIDEO_HEVCProfileMain10; 6931 break; 6932 default: 6933 DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__); 6934 return false; 6935 } 6936 } 6937 } 6938 6939 if (*eLevel == 0 && !m_level_set) { 6940 *eLevel = OMX_VIDEO_HEVCLevelMax; 6941 } 6942 6943 if (*eProfile == OMX_VIDEO_HEVCProfileMain) { 6944 profile_tbl = (unsigned int const *)hevc_profile_level_table; 6945 } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) { 6946 profile_tbl = (unsigned int const *) 6947 (&hevc_profile_level_table[HEVC_MAIN10_START]); 6948 } else { 6949 DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile); 6950 return false; 6951 } 6952 } else { 6953 DEBUG_PRINT_ERROR("Invalid codec type"); 6954 return false; 6955 } 6956 6957 mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)* 6958 ((m_sVenc_cfg.dvs_width + 15)>> 4); 6959 6960 if ((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) { 6961 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) 6962 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 6963 6964 if (codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) 6965 profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; 6966 6967 { 6968 new_level = profile_level.level; 6969 new_profile = codec_profile.profile; 6970 return true; 6971 } 6972 } 6973 6974 if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) { 6975 *eLevel = rc_off_level; //No level calculation for RC_OFF 6976 profile_level_found = true; 6977 return true; 6978 } 6979 6980 mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; 6981 6982 bool h264, ltr, hlayers; 6983 unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame; 6984 h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264; 6985 ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB)); 6986 hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P && 6987 ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0])); 6988 6989 /* Hybrid HP reference buffers: 6990 layers = 1, 2 need 1 reference buffer 6991 layers = 3, 4 need 2 reference buffers 6992 layers = 5, 6 need 3 reference buffers 6993 */ 6994 6995 if(hier_layers.hier_mode == HIER_P_HYBRID) 6996 hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16); 6997 6998 do { 6999 if (mb_per_frame <= (unsigned int)profile_tbl[0]) { 7000 if (mb_per_sec <= (unsigned int)profile_tbl[1]) { 7001 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) { 7002 if (h264 && (ltr || hlayers || hybridp)) { 7003 // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings 7004 new_level = (int)profile_tbl[3]; 7005 new_profile = (int)profile_tbl[4]; 7006 profile_level_found = true; 7007 DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u", 7008 ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level, 7009 MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB)); 7010 break; 7011 } else { 7012 new_level = (int)profile_tbl[3]; 7013 new_profile = (int)profile_tbl[4]; 7014 profile_level_found = true; 7015 DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level); 7016 break; 7017 } 7018 } 7019 } 7020 } 7021 profile_tbl = profile_tbl + MAX_PROFILE_PARAMS; 7022 } while (profile_tbl[0] != 0); 7023 7024 if (profile_level_found != true) { 7025 DEBUG_PRINT_LOW("ERROR: Unsupported profile/level"); 7026 return false; 7027 } 7028 7029 if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) 7030 || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax) 7031 || (*eLevel == OMX_VIDEO_HEVCLevelMax)) { 7032 *eLevel = new_level; 7033 } 7034 7035 DEBUG_PRINT_LOW("%s: Returning with eProfile = %u" 7036 "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel); 7037 7038 return true; 7039 } 7040 #ifdef _ANDROID_ICS_ 7041 bool venc_dev::venc_set_meta_mode(bool mode) 7042 { 7043 metadatamode = mode; 7044 return true; 7045 } 7046 #endif 7047 7048 bool venc_dev::venc_is_video_session_supported(unsigned long width, 7049 unsigned long height) 7050 { 7051 if ((width * height < capability.min_width * capability.min_height) || 7052 (width * height > capability.max_width * capability.max_height)) { 7053 DEBUG_PRINT_ERROR( 7054 "Unsupported video resolution WxH = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)", 7055 width, height, capability.min_width, capability.min_height, 7056 capability.max_width, capability.max_height); 7057 return false; 7058 } 7059 7060 DEBUG_PRINT_LOW("video session supported"); 7061 return true; 7062 } 7063 7064 bool venc_dev::venc_set_batch_size(OMX_U32 batchSize) 7065 { 7066 struct v4l2_control control; 7067 int ret; 7068 7069 control.id = V4L2_CID_VIDC_QBUF_MODE; 7070 control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD; 7071 7072 ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); 7073 if (ret) { 7074 DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret); 7075 return false; 7076 } 7077 7078 mBatchSize = batchSize; 7079 DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize); 7080 return true; 7081 } 7082 7083 venc_dev::BatchInfo::BatchInfo() 7084 : mNumPending(0) { 7085 pthread_mutex_init(&mLock, NULL); 7086 for (int i = 0; i < kMaxBufs; ++i) { 7087 mBufMap[i] = kBufIDFree; 7088 } 7089 } 7090 7091 int venc_dev::BatchInfo::registerBuffer(int bufferId) { 7092 pthread_mutex_lock(&mLock); 7093 int availId = 0; 7094 for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId); 7095 if (availId >= kMaxBufs) { 7096 DEBUG_PRINT_ERROR("Failed to find free entry !"); 7097 pthread_mutex_unlock(&mLock); 7098 return -1; 7099 } 7100 mBufMap[availId] = bufferId; 7101 mNumPending++; 7102 pthread_mutex_unlock(&mLock); 7103 return availId; 7104 } 7105 7106 int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) { 7107 pthread_mutex_lock(&mLock); 7108 if (v4l2Id >= kMaxBufs || v4l2Id < 0) { 7109 DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id); 7110 pthread_mutex_unlock(&mLock); 7111 return -1; 7112 } 7113 if (mBufMap[v4l2Id] == kBufIDFree) { 7114 DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id); 7115 pthread_mutex_unlock(&mLock); 7116 return -1; 7117 } 7118 int bufferId = mBufMap[v4l2Id]; 7119 mBufMap[v4l2Id] = kBufIDFree; 7120 mNumPending--; 7121 pthread_mutex_unlock(&mLock); 7122 return bufferId; 7123 } 7124 7125 bool venc_dev::BatchInfo::isPending(int bufferId) { 7126 pthread_mutex_lock(&mLock); 7127 int existsId = 0; 7128 for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId); 7129 pthread_mutex_unlock(&mLock); 7130 return existsId < kMaxBufs; 7131 } 7132 7133 int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) { 7134 int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1; 7135 return fd; 7136 } 7137 7138 int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) { 7139 int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1; 7140 return off; 7141 } 7142 7143 int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) { 7144 int size = hnd && (index + hnd->numFds) < hnd->numInts ? 7145 hnd->data[2*hnd->numFds + index] : -1; 7146 return size; 7147 } 7148 7149 int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) { 7150 int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ? 7151 hnd->data[3*hnd->numFds + index] : 0; 7152 return usage; 7153 } 7154 7155 int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) { 7156 int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ? 7157 hnd->data[4*hnd->numFds + index] : -1; 7158 return size; 7159 } 7160 7161 #ifdef _VQZIP_ 7162 venc_dev::venc_dev_vqzip::venc_dev_vqzip() 7163 { 7164 mLibHandle = NULL; 7165 pthread_mutex_init(&lock, NULL); 7166 } 7167 7168 bool venc_dev::venc_dev_vqzip::init() 7169 { 7170 bool status = true; 7171 if (mLibHandle) { 7172 DEBUG_PRINT_ERROR("VQZIP init called twice"); 7173 status = false; 7174 } 7175 if (status) { 7176 mLibHandle = dlopen("libvqzip.so", RTLD_NOW); 7177 if (mLibHandle) { 7178 mVQZIPInit = (vqzip_init_t) 7179 dlsym(mLibHandle,"VQZipInit"); 7180 mVQZIPDeInit = (vqzip_deinit_t) 7181 dlsym(mLibHandle,"VQZipDeInit"); 7182 mVQZIPComputeStats = (vqzip_compute_stats_t) 7183 dlsym(mLibHandle,"VQZipComputeStats"); 7184 if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats) 7185 status = false; 7186 } else { 7187 DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror()); 7188 status = false; 7189 } 7190 if (status) { 7191 mVQZIPHandle = mVQZIPInit(); 7192 } 7193 } 7194 if (!status && mLibHandle) { 7195 dlclose(mLibHandle); 7196 mLibHandle = NULL; 7197 mVQZIPHandle = NULL; 7198 mVQZIPInit = NULL; 7199 mVQZIPDeInit = NULL; 7200 mVQZIPComputeStats = NULL; 7201 } 7202 return status; 7203 } 7204 7205 int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData) 7206 { 7207 VQZipStatus result; 7208 VQZipStats *pStats = (VQZipStats *)extraData; 7209 pConfig.pSEIPayload = NULL; 7210 unsigned long size; 7211 7212 if (!pBuf || !pStats || !mVQZIPHandle) { 7213 DEBUG_PRINT_ERROR("Invalid data passed to stats function"); 7214 } 7215 result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats); 7216 return (result < 0); 7217 } 7218 7219 void venc_dev::venc_dev_vqzip::deinit() 7220 { 7221 if (mLibHandle) { 7222 pthread_mutex_lock(&lock); 7223 dlclose(mLibHandle); 7224 mVQZIPDeInit(mVQZIPHandle); 7225 mLibHandle = NULL; 7226 mVQZIPHandle = NULL; 7227 mVQZIPInit = NULL; 7228 mVQZIPDeInit = NULL; 7229 mVQZIPComputeStats = NULL; 7230 pthread_mutex_unlock(&lock); 7231 } 7232 } 7233 7234 venc_dev::venc_dev_vqzip::~venc_dev_vqzip() 7235 { 7236 DEBUG_PRINT_HIGH("Destroy C2D instance"); 7237 if (mLibHandle) { 7238 dlclose(mLibHandle); 7239 } 7240 mLibHandle = NULL; 7241 pthread_mutex_destroy(&lock); 7242 } 7243 #endif 7244 7245 encExtradata::encExtradata(class omx_venc *venc_handle) 7246 { 7247 mCount = 0; 7248 mSize = 0; 7249 mUaddr = NULL; 7250 memset(&mIon, -1, sizeof(struct venc_ion)); 7251 memset(mIndex, 0, sizeof(mIndex)); 7252 mVencHandle = venc_handle; 7253 mDbgEtbCount = 0; 7254 pthread_mutex_init(&lock, NULL); 7255 vqzip_sei_found = false; 7256 } 7257 7258 encExtradata::~encExtradata() 7259 { 7260 __free(); 7261 mCount = 0; 7262 mSize = 0; 7263 mVencHandle = NULL; 7264 pthread_mutex_destroy(&lock); 7265 } 7266 7267 OMX_ERRORTYPE encExtradata::__allocate() 7268 { 7269 ssize_t totalSize = (mSize * mCount + 4095) & (~4095); 7270 if (!mVencHandle) { 7271 return OMX_ErrorInsufficientResources; 7272 } 7273 if (mUaddr || !totalSize) { 7274 return OMX_ErrorNone; 7275 } 7276 mIon.ion_device_fd = mVencHandle->alloc_map_ion_memory( 7277 totalSize, 7278 &mIon.ion_alloc_data, 7279 &mIon.fd_ion_data, 0); 7280 if (mIon.ion_device_fd < 0) { 7281 DEBUG_PRINT_ERROR("Failed to alloc extradata memory: %zd", totalSize); 7282 DEBUG_PRINT_ERROR("Check if OMX_QTIIndexParamVideoEnableRoiInfo is set."); 7283 return OMX_ErrorInsufficientResources; 7284 } 7285 mUaddr = (char *)mmap(NULL, totalSize, 7286 PROT_READ|PROT_WRITE, MAP_SHARED, 7287 mIon.fd_ion_data.fd , 0); 7288 if (mUaddr == MAP_FAILED) { 7289 DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); 7290 close(mIon.fd_ion_data.fd); 7291 mVencHandle->free_ion_memory(&mIon); 7292 return OMX_ErrorInsufficientResources; 7293 } 7294 for (unsigned i = 0; i < mCount; i++) { 7295 mIndex[i].status = FREE; 7296 mIndex[i].cookie = NULL; 7297 } 7298 return OMX_ErrorNone; 7299 } 7300 7301 int encExtradata::__get(char **userptr, int *fd, unsigned *offset, ssize_t *size, int type) 7302 { 7303 unsigned i = 0; 7304 if (__allocate() != OMX_ErrorNone) { 7305 return -1; 7306 } 7307 for (i = 0; i < mCount; i++) { 7308 if (mIndex[i].status == type) { 7309 mIndex[i].status = BUSY; 7310 break; 7311 } 7312 } 7313 if (i >= mCount) { 7314 DEBUG_PRINT_HIGH("No Free extradata available"); 7315 return -1; 7316 } 7317 *userptr = mUaddr + i * mSize; 7318 *fd = mIon.fd_ion_data.fd; 7319 *offset = i * mSize; 7320 *size = mSize; 7321 return i; 7322 } 7323 7324 OMX_ERRORTYPE encExtradata::get(char **userptr, int *fd, unsigned *offset, ssize_t *size) { 7325 int index; 7326 *userptr = NULL; 7327 *fd = -1; 7328 *offset = 0; 7329 *size = 0; 7330 pthread_mutex_lock(&lock); 7331 index = __get(userptr, fd, offset, size, FREE); 7332 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size); 7333 pthread_mutex_unlock(&lock); 7334 return index < 0 ? OMX_ErrorInsufficientResources : OMX_ErrorNone; 7335 } 7336 7337 OMX_ERRORTYPE encExtradata::get(void *cookie, char **userptr, int *fd, unsigned *offset, ssize_t *size) 7338 { 7339 OMX_ERRORTYPE rc = OMX_ErrorNone; 7340 unsigned int i; 7341 *userptr = NULL; 7342 *fd = -1; 7343 *offset = 0; 7344 *size = 0; 7345 pthread_mutex_lock(&lock); 7346 for (i = 0; i < mCount; i++) { 7347 if (mIndex[i].cookie == cookie) { 7348 break; 7349 } 7350 } 7351 if (i < mCount) { 7352 *userptr = mUaddr + i * mSize; 7353 *fd = mIon.fd_ion_data.fd; 7354 *offset = i * mSize; 7355 *size = mSize; 7356 } else { 7357 int index = __get(userptr, fd, offset, size, FREE); 7358 if (index < 0 ) { 7359 DEBUG_PRINT_HIGH("%s: failed(%d, %p)", __func__, i, cookie); 7360 __debug(); 7361 rc = OMX_ErrorInsufficientResources; 7362 } 7363 } 7364 DEBUG_PRINT_LOW("%s: (%p, %p, %d, %u, %zd)", __func__, cookie, *userptr, *fd, *offset, *size); 7365 pthread_mutex_unlock(&lock); 7366 return rc; 7367 } 7368 7369 OMX_ERRORTYPE encExtradata::getForConfig(char **userptr, int *fd, unsigned *offset, ssize_t *size) 7370 { 7371 OMX_ERRORTYPE rc = OMX_ErrorNone; 7372 unsigned int i; 7373 int found = -1; 7374 pthread_mutex_lock(&lock); 7375 found = __get(userptr, fd, offset, size, FOR_CONFIG); 7376 if (found < 0) { 7377 found = __get(userptr, fd, offset, size, FREE); 7378 } 7379 7380 if (found < 0) { 7381 DEBUG_PRINT_HIGH("%s: failed (%d)", __func__, found); 7382 __debug(); 7383 rc = OMX_ErrorInsufficientResources; 7384 } else { 7385 mIndex[found].status = FOR_CONFIG; 7386 DEBUG_PRINT_LOW("%s: (%p, %d, %d, %zd)", __func__, *userptr, *fd, *offset, *size); 7387 } 7388 pthread_mutex_unlock(&lock); 7389 return rc; 7390 } 7391 7392 OMX_ERRORTYPE encExtradata::put(char *userptr) 7393 { 7394 OMX_ERRORTYPE rc = OMX_ErrorNone; 7395 int index = (userptr - mUaddr)/mSize; 7396 pthread_mutex_lock(&lock); 7397 if (!userptr) { 7398 DEBUG_PRINT_HIGH("Userptr is NULL"); 7399 rc = OMX_ErrorBadParameter; 7400 } else if (index < 0) { 7401 DEBUG_PRINT_HIGH("Userptr is not in valid range: %p", userptr); 7402 __debug(); 7403 rc = OMX_ErrorBadParameter; 7404 } else { 7405 mIndex[index].status = FREE; 7406 mIndex[index].cookie = NULL; 7407 DEBUG_PRINT_LOW("%s: (%d, %p)", __func__, index, userptr); 7408 } 7409 pthread_mutex_unlock(&lock); 7410 return rc; 7411 } 7412 7413 OMX_ERRORTYPE encExtradata::peek(unsigned index, char **userptr, int *fd, unsigned* offset, ssize_t *size) 7414 { 7415 OMX_ERRORTYPE rc = OMX_ErrorNone; 7416 *userptr = 0; 7417 *fd = -1; 7418 *offset = 0; 7419 *size = 0; 7420 pthread_mutex_lock(&lock); 7421 if (index < mCount) { 7422 rc = __allocate(); 7423 if (rc == OMX_ErrorNone) { 7424 *userptr = mUaddr + index * mSize; 7425 *fd = mIon.fd_ion_data.fd; 7426 *offset = index * mSize; 7427 *size = mSize; 7428 } 7429 } 7430 DEBUG_PRINT_LOW("%s: (%d, %p, %d, %u, %zd)", __func__, index, *userptr, *fd, *offset, *size); 7431 pthread_mutex_unlock(&lock); 7432 return rc; 7433 } 7434 7435 void encExtradata::setCookieForConfig(void *cookie) 7436 { 7437 char *userptr; 7438 int fd; 7439 unsigned offset; 7440 ssize_t size; 7441 pthread_mutex_lock(&lock); 7442 int found = __get(&userptr, &fd, &offset, &size, FOR_CONFIG); 7443 if (found >= 0) { 7444 mIndex[found].cookie = cookie; 7445 } else { 7446 DEBUG_PRINT_HIGH("Failed to set cookie for extradata: %d, cookie: %p\n", 7447 found, cookie); 7448 __debug(); 7449 } 7450 mDbgEtbCount++; 7451 pthread_mutex_unlock(&lock); 7452 } 7453 7454 void encExtradata::__free() 7455 { 7456 ssize_t totalSize = (mCount * mSize + 4095) & (~4095); 7457 if (mUaddr) { 7458 munmap((void *)mUaddr, totalSize); 7459 mUaddr = NULL; 7460 } 7461 if (mIon.fd_ion_data.fd >= 0) { 7462 if (mVencHandle) 7463 mVencHandle->free_ion_memory(&mIon); 7464 close(mIon.fd_ion_data.fd); 7465 mIon.fd_ion_data.fd = -1; 7466 } 7467 for (unsigned i = 0; i < mCount; i++) { 7468 mIndex[i].status = FREE; 7469 mIndex[i].cookie = NULL; 7470 } 7471 } 7472 7473 void encExtradata::update(unsigned int count, ssize_t size) 7474 { 7475 pthread_mutex_lock(&lock); 7476 __free(); 7477 mCount = count <= MAX_V4L2_BUFS ? count : MAX_V4L2_BUFS; 7478 mSize = size; 7479 DEBUG_PRINT_LOW("%s: (%d, %zd)", __func__, mCount, mSize); 7480 pthread_mutex_unlock(&lock); 7481 } 7482 7483 void encExtradata::__debug() 7484 { 7485 DEBUG_PRINT_HIGH("encExtradata: this: %p, mCount: %d, mSize: %zd, mUaddr: %p, mVencHandle: %p", 7486 this, mCount, mSize, mUaddr, mVencHandle); 7487 for (unsigned i = 0; i < mCount; i++) { 7488 DEBUG_PRINT_HIGH("index: %d, status: %d, cookie: %p\n", i, mIndex[i].status, mIndex[i].cookie); 7489 } 7490 } 7491 7492 ssize_t encExtradata::getBufferSize() 7493 { 7494 return mSize; 7495 } 7496 7497 unsigned int encExtradata::getBufferCount() 7498 { 7499 return mCount; 7500 } 7501