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 */
init_profiler(profile_database_t * ps_profile_data)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 */
profile_sample_time()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 */
profile_start(profile_database_t * ps_profile_data)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 */
profile_sample_time_end(profile_database_t * ps_profile_data)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 */
profile_get_time_taken(profile_database_t * ps_profile_data)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 */
profile_get_average(profile_database_t * ps_profile_data)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 */
profile_get_avg_time(profile_database_t * ps_profile_data)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 */
profile_get_peak(profile_database_t * ps_profile_data)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 */
profile_get_peak_time(profile_database_t * ps_profile_data)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 */
profile_end(profile_database_t * ps_profile_data,char * msg)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 */
profile_stop(profile_database_t * ps_profile_data,char * msg)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