1 /****************************************************************************** 2 * 3 * Copyright (C) 2018 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ***************************************************************************** 18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore 19 */ 20 21 /*! 22 ****************************************************************************** 23 * \file ihevce_profile.c 24 * 25 * \brief 26 * This file contains Profiling related functions 27 * 28 * \date 29 * 18/09/2012 30 * 31 * \author 32 * Ittiam 33 * 34 * 35 * List of Functions 36 * 37 * 38 ****************************************************************************** 39 */ 40 41 /*****************************************************************************/ 42 /* File Includes */ 43 /*****************************************************************************/ 44 45 /* System include files */ 46 #include <stdio.h> 47 #include <string.h> 48 #include <stdlib.h> 49 #include <assert.h> 50 #include <stdarg.h> 51 #include <math.h> 52 53 /* User include files */ 54 #include "ihevc_typedefs.h" 55 #include "ihevce_profile.h" 56 #include "itt_video_api.h" 57 #include "ihevce_api.h" 58 #include <sys/time.h> 59 60 /* print attributes */ 61 62 /* print everything on console */ 63 #define PRINTF(x, y, ...) printf(__VA_ARGS__) 64 65 #if PROFILE_ENABLE 66 67 /*! 68 ****************************************************************************** 69 * \if Function name : init_profiler \endif 70 * 71 * \brief 72 * Initialization of profiling context 73 * 74 ***************************************************************************** 75 */ 76 void init_profiler(profile_database_t *ps_profile_data) 77 { 78 memset(ps_profile_data, 0, sizeof(*ps_profile_data)); 79 80 return; 81 } 82 83 /*! 84 ****************************************************************************** 85 * \if Function name : profile_sample_time \endif 86 * 87 * \brief 88 * This function calls the system function gettimeofday() to get the current 89 * time 90 * 91 ***************************************************************************** 92 */ 93 ULWORD64 profile_sample_time() 94 { 95 struct timeval s_time; 96 ULWORD64 u8_curr_time; 97 98 gettimeofday(&s_time, NULL); 99 u8_curr_time = (((ULWORD64)s_time.tv_sec * 1000 * 1000) + (ULWORD64)(s_time.tv_usec)); 100 101 return u8_curr_time; 102 } 103 104 /*! 105 ****************************************************************************** 106 * \if Function name : profile_start \endif 107 * 108 * \brief 109 * This function samples current time 110 * 111 ***************************************************************************** 112 */ 113 void profile_start(profile_database_t *ps_profile_data) 114 { 115 ps_profile_data->u8_time_start = profile_sample_time(); 116 assert(0 == ps_profile_data->u1_sample_taken_flag); 117 ps_profile_data->u1_sample_taken_flag = 1; 118 119 return; 120 } 121 122 /*! 123 ****************************************************************************** 124 * \if Function name : profile_sample_time_end \endif 125 * 126 * \brief 127 * This function is called for getting current time after a process call. 128 * It also updates this info in profile database 129 * 130 ***************************************************************************** 131 */ 132 void profile_sample_time_end(profile_database_t *ps_profile_data) 133 { 134 ps_profile_data->u8_time_end = profile_sample_time(); 135 assert(1 == ps_profile_data->u1_sample_taken_flag); 136 ps_profile_data->u1_sample_taken_flag = 0; 137 138 return; 139 } 140 141 /*! 142 ****************************************************************************** 143 * \if Function name : profile_get_time_taken \endif 144 * 145 * \brief 146 * This function computes the time taken by the process call 147 * 148 ***************************************************************************** 149 */ 150 void profile_get_time_taken(profile_database_t *ps_profile_data) 151 { 152 if(ps_profile_data->u8_time_end < ps_profile_data->u8_time_start) 153 { 154 /* Timer overflow */ 155 ps_profile_data->u8_cur_time = 156 ((LWORD64)0xFFFFFFFF - ps_profile_data->u8_time_start) + ps_profile_data->u8_time_end; 157 } 158 else 159 { 160 ps_profile_data->u8_cur_time = 161 ps_profile_data->u8_time_end - ps_profile_data->u8_time_start; 162 } 163 } 164 165 /*! 166 ****************************************************************************** 167 * \if Function name : profile_get_average \endif 168 * 169 * \brief 170 * This function computes the average time taken by the process calls so far 171 * 172 ***************************************************************************** 173 */ 174 void profile_get_average(profile_database_t *ps_profile_data) 175 { 176 ps_profile_data->u8_total_time += ps_profile_data->u8_cur_time; 177 ps_profile_data->u4_num_profile_calls++; 178 179 ps_profile_data->u8_avg_time = 180 (ps_profile_data->u8_total_time / ps_profile_data->u4_num_profile_calls); 181 182 return; 183 } 184 185 /*! 186 ****************************************************************************** 187 * \if Function name : profile_get_avg_time \endif 188 * 189 * \brief 190 * This function returns the average time taken by the process calls so far 191 * 192 ***************************************************************************** 193 */ 194 int profile_get_avg_time(profile_database_t *ps_profile_data) 195 { 196 return (UWORD32)(ps_profile_data->u8_avg_time); 197 } 198 199 /*! 200 ****************************************************************************** 201 * \if Function name : profile_get_peak \endif 202 * 203 * \brief 204 * This function computes the peak time taken by the process calls so far 205 * 206 ***************************************************************************** 207 */ 208 void profile_get_peak(profile_database_t *ps_profile_data) 209 { 210 if(ps_profile_data->u8_cur_time > ps_profile_data->u8_peak_time) 211 { 212 ps_profile_data->u8_peak_time = ps_profile_data->u8_cur_time; 213 } 214 return; 215 } 216 217 /*! 218 ****************************************************************************** 219 * \if Function name : profile_get_peak \endif 220 * 221 * \brief 222 * This function returns the peak time taken by the process calls so far 223 * 224 ***************************************************************************** 225 */ 226 int profile_get_peak_time(profile_database_t *ps_profile_data) 227 { 228 return (UWORD32)(ps_profile_data->u8_peak_time); 229 } 230 231 /*! 232 ****************************************************************************** 233 * \if Function name : profile_end \endif 234 * 235 * \brief 236 * This function prints the profile data - time taken by the last process 237 * call, average time so far and peak time so far 238 * 239 ***************************************************************************** 240 */ 241 void profile_end(profile_database_t *ps_profile_data, char *msg) 242 { 243 printf("**********************************************\n"); 244 if(msg) 245 { 246 printf( 247 "IHEVC : %s, Avg Process Time: %d micro-seconds\n", 248 msg, 249 (UWORD32)(ps_profile_data->u8_avg_time)); 250 printf( 251 "IHEVC : %s, Peak Process Time : %d micro-seconds\n", 252 msg, 253 (UWORD32)(ps_profile_data->u8_peak_time)); 254 } 255 else 256 { 257 printf( 258 "IHEVC : %s, Avg Process Time: %d micro-seconds\n", 259 "<unknown>", 260 (UWORD32)(ps_profile_data->u8_avg_time)); 261 printf( 262 "IHEVC : %s, Peak Process Time : %d micro-seconds\n", 263 "<unknown>", 264 (UWORD32)(ps_profile_data->u8_peak_time)); 265 } 266 return; 267 } 268 269 /*! 270 ****************************************************************************** 271 * \if Function name : profile_stop \endif 272 * 273 * \brief 274 * This function prints the profile time 275 * 276 ***************************************************************************** 277 */ 278 void profile_stop(profile_database_t *ps_profile_data, char *msg) 279 { 280 /* Get current time - This corresponds to time after the process call */ 281 profile_sample_time_end(ps_profile_data); 282 /* Get time taken for the process call */ 283 profile_get_time_taken(ps_profile_data); 284 /* Calculate average time taken so far */ 285 profile_get_average(ps_profile_data); 286 /* Calculate peak time per process call taken so far */ 287 profile_get_peak(ps_profile_data); 288 289 if(msg) 290 { 291 printf("%s, fps: :%10.3f", msg, (DOUBLE)(1000000.0 / ps_profile_data->u8_avg_time)); 292 } 293 294 return; 295 } 296 297 #endif /* #if PROFILE_ENABLE */ 298