4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
30 #include <sys/utsname.h>
31 #include <sys/resource.h>
40 static void __free_cps(void);
41 static int __get_cp_index(char* name);
43 static void __free_accums(void);
44 static int __get_accum_index(char* name);
47 gst_ta_checkpoint ** g_cps = NULL;
48 static int g_cp_index = 0;
50 gst_ta_accum_item ** g_accums = NULL;
51 static int g_accum_index = 0;
52 static int g_accum_longest_name = 0;
53 static unsigned long g_accum_first_time = 0xFFFFFFFF;
54 static int g_enable = 0;
56 #define MMTA_ENV_NAME "MMTA_ENABLE"
58 void __set_enable_by_env ()
60 char* env = getenv (MMTA_ENV_NAME);
61 if (env != NULL && strcmp (env,"1") == 0)
67 __set_enable_by_env();
75 g_cps = (gst_ta_checkpoint **) malloc ( GST_TA_MAX_CHECKPOINT * sizeof(gst_ta_checkpoint *) );
79 g_accums = (gst_ta_accum_item **) malloc ( GST_TA_MAX_CHECKPOINT * sizeof(gst_ta_accum_item *) );
83 g_accum_first_time = 0xFFFFFFFF;
88 int gst_ta_release(void)
96 g_accum_first_time = 0xFFFFFFFF;
101 void gst_ta_set_enable(int enable)
103 printf("MMTA : setting enable to %d\n", enable);
107 int gst_ta_get_numof_checkpoints()
112 char* gst_ta_fmt(const char* fmt, ...)
114 static char ta_buf[512];
117 memset(ta_buf, '\0', 512);
120 vsnprintf(ta_buf, 512, fmt, args);
127 int gst_ta_add_checkpoint(char* name, int show, char* filename, int line)
129 gst_ta_checkpoint * cp = NULL;
138 if ( g_cp_index == GST_TA_MAX_CHECKPOINT )
144 if( strlen ( name ) == 0 )
147 cp = ( gst_ta_checkpoint * ) malloc( sizeof( gst_ta_checkpoint ) );
151 cp->name = strdup (name);
159 printf("[CHECK-POINT] %s...(%s:%d)\n", name, filename, line );
161 gettimeofday( &t, NULL );
162 cp->timestamp = t.tv_sec*1000000L + t.tv_usec;
163 #ifdef GST_EXT_TA_UNIT_MSEC
164 cp->timestamp = (cp->timestamp >= 1000)?cp->timestamp/1000:0;
167 g_cps[g_cp_index] = cp;
174 void gst_ta_show_checkpoints(void)
181 printf("BEGIN RESULT ============================\n");
182 for ( i = 0; i < g_cp_index; i++ )
184 printf("[%d] %s : %ld us.\n", i, g_cps[i]->name, g_cps[i]->timestamp);
186 printf("END RESULT ============================\n");
189 void gst_ta_show_diff(char* name1, char* name2)
195 printf("Time takes from [%s] to [%s] : %ld us.\n", name1, name2, gst_ta_get_diff(name1, name2));
198 unsigned long gst_ta_get_diff(char* name1, char* name2)
206 /* fail if bad param. */
207 if ( !name1 || !name2 )
211 if ( strcmp( name1, name2 ) == 0 )
215 if ( ( cp1 = __get_cp_index(name1) ) == -1 )
218 if ( ( cp2 = __get_cp_index(name2) ) == -1 )
222 * return value must be positive value.
223 * bcz the value of higher index of g_cps always higher than lower one. */
224 return g_cps[cp2]->timestamp - g_cps[cp1]->timestamp;
228 static int __get_cp_index(char* name)
235 for ( i = 0; i < g_cp_index; i++ )
237 if ( strcmp( name, g_cps[i]->name ) == 0 )
244 static int __get_accum_index(char* name)
251 for ( i = 0; i < g_accum_index; i++ )
253 if ( strcmp( name, g_accums[i]->name ) == 0 )
260 static void __free_cps(void)
267 for ( i = 0; i < g_cp_index; i++ )
271 if ( g_cps[i]->name )
272 free ( g_cps[i]->name );
286 static void __free_accums(void)
293 for ( i = 0; i < g_accum_index; i++ )
297 if ( g_accums[i]->name )
298 free ( g_accums[i]->name );
300 free ( g_accums[i] );
307 g_accum_longest_name = 0;
314 int gst_ta_accum_item_begin(char* name, int show, char* filename, int line)
316 gst_ta_accum_item * accum = NULL;
329 if ( g_accum_index == GST_TA_MAX_ACCUM )
335 name_len = strlen(name);
339 /* if 'name' is new one. create new item. */
340 if ( (index = __get_accum_index(name)) == -1 )
342 accum = ( gst_ta_accum_item * ) malloc( sizeof( gst_ta_accum_item ) );
347 memset( accum, 0, sizeof (gst_ta_accum_item) );
348 accum->elapsed_min = 0xFFFFFFFF;
350 accum->name = strdup (name);
357 /* add it to list. */
358 g_accums[g_accum_index] = accum;
361 if ( g_accum_longest_name < name_len )
362 g_accum_longest_name = name_len;
367 accum = g_accums[index];
370 /* verify pairs of begin, end. */
371 if (accum->on_estimate)
373 printf("[%s] is not 'end'ed!\n", accum->name);
374 accum->num_unpair ++;
379 gettimeofday( &t, NULL );
380 accum->timestamp = t.tv_sec*1000000L + t.tv_usec;
381 #ifdef GST_EXT_TA_UNIT_MSEC
382 accum->timestamp = ( accum->timestamp >= 1000) ? accum->timestamp/1000 : 0;
384 accum->on_estimate = 1;
386 if ( accum->first_start == 0 ) { /* assum that timestamp never could be zero.*/
387 accum->first_start = accum->timestamp;
389 if ( g_accum_first_time > accum->first_start )
390 g_accum_first_time = accum->first_start ;
394 printf("[ACCUM BEGIN] %s : %ld ---(%s:%d)\n", name, accum->timestamp, filename, line );
401 int gst_ta_accum_item_end(char* name, int show, char* filename, int line)
403 gst_ta_accum_item * accum = NULL;
404 unsigned int tval = 0;
415 /* get time first for more accuracy. */
416 gettimeofday( &t, NULL );
418 if ( g_accum_index == GST_TA_MAX_ACCUM )
424 if( strlen ( name ) == 0 )
427 /* varify the 'name' is already exist. */
428 if ( (index = __get_accum_index(name)) == -1 )
430 printf("[%s] is not added before!\n", name);
434 accum = g_accums[index];
436 /* verify pairs of begin, end. */
437 if (!accum->on_estimate)
439 printf("[%s] is not 'begin' yet!\n", accum->name);
440 accum->num_unpair ++;
444 /* get current timestamp. */
445 tval = t.tv_sec*1000000L + t.tv_usec;
446 #ifdef GST_EXT_TA_UNIT_MSEC
447 tval = (tval>=1000) ? tval/1000 : 0;
450 /* update last_end */
451 accum->last_end = tval;
453 /* make get elapsed time. */
454 tval = tval - accum->timestamp;
457 accum->elapsed_max = tval > accum->elapsed_max ? tval : accum->elapsed_max;
458 accum->elapsed_min = tval < accum->elapsed_min ? tval : accum->elapsed_min;
461 printf("[ACCUM END] %s : %ld + %u ---(%s:%d)\n", name, accum->elapsed_accum, tval, filename, line );
463 /* add elapsed time */
464 accum->elapsed_accum += tval;
465 accum->on_estimate = 0;
470 void __print_some_info(FILE* fp)
478 "\nThe following content is automatically generated by gstreamer\n \
479 with GST_EXT_TIME_ANALYSIS feature. This feature can affects\n \
480 performance of multimedia functionality. so if you want to\n \
481 disable it. just comment the feature in /limo-middleware/\n \
482 multimedia-framework/media-service/msl_feature_config.py\n" );
485 /* General infomation */
488 char hostname[256] = {'\0',};
489 char ctime_str[256] = {'\0',};
491 struct rusage r_usage;
493 fprintf(fp, "\n[[ General info ]]\n");
497 fprintf(fp, "Date : %s", ctime_r(&t_val, ctime_str) );
500 if ( gethostname(hostname, 255) == 0 && uname(&uts) >= 0 )
502 fprintf(fp, "Hostname : %s\n", hostname);
503 fprintf(fp, "System : %s\n", uts.sysname);
504 fprintf(fp, "Machine : %s\n", uts.machine);
505 fprintf(fp, "Nodename : %s\n", uts.nodename);
506 fprintf(fp, "Release : %s \n", uts.release);
507 fprintf(fp, "Version : %s \n", uts.version);
511 fprintf(fp, "Process priority : %d\n", getpriority(PRIO_PROCESS, getpid()) );
512 getrusage(RUSAGE_SELF, &r_usage);
513 fprintf(fp, "CPU usage : User = %ld.%06ld, System = %ld.%06ld\n",
514 r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec,
515 r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec );
520 /* host environment variables */
522 extern char** environ;
523 char** env = environ;
525 fprintf(fp, "\n[[ Host environment variables ]]\n");
528 fprintf(fp, "%s\n", *env);
533 /* applied target feature */
535 fprintf(fp, "\n[[ Applied target feature ]]\n");
536 #ifdef GST_EXT_TIME_ANALYSIS
537 fprintf(fp, "GST_EXT_TIME_ANALYSIS\n");
539 #ifdef GST_EXT_SKIP_RESCAN_REGISTRY
540 fprintf(fp, "GST_EXT_SKIP_RESCAN_REGISTRY\n");
542 #ifdef GST_EXT_USE_TINY_REGISTRY
544 fprintf(fp, "GST_EXT_USE_TINY_REGISTRY\n");
546 #ifdef GST_EXT_PAD_LINK_UNCHECKED
547 fprintf(fp, "GST_EXT_PAD_LINK_UNCHECKED\n");
549 #ifdef GST_EXT_DFBVIDEOSINK_IPP
550 fprintf(fp, "GST_EXT_DFBVIDEOSINK_IPP\n");
552 #ifdef GST_EXT_REDUCE_PLUGIN_NUM
553 fprintf(fp, "GST_EXT_REDUCE_PLUGIN_NUM\n");
555 #ifdef GST_EXT_USE_PDP_NETWORK
556 fprintf(fp, "GST_EXT_USE_PDP_NETWORK\n");
558 #ifdef GST_EXT_VOLUME_WITHOUT_LIBOIL
559 fprintf(fp, "GST_EXT_VOLUME_WITHOUT_LIBOIL\n");
561 #ifdef GST_EXT_DECODEBIN_QUEUE_ENLARGE
562 fprintf(fp, "GST_EXT_DECODEBIN_QUEUE_ENLARGE\n");
565 /* Camcorder releated feature */
567 #ifdef GST_EXT_NONBLOCKDQUE
568 fprintf(fp, "GST_EXT_NONBLOCKDQUE\n");
570 #ifdef GST_EXT_RENEGOTIATION
571 fprintf(fp, "GST_EXT_RENEGOTIATION\n");
573 #ifdef GST_EXT_MOBILECAMERA
574 fprintf(fp, "GST_EXT_MOBILECAMERA\n");
576 #ifdef GST_EXT_VIDEOSCALE_IPP
577 fprintf(fp, "GST_EXT_VIDEOSCALE_IPP\n");
579 #ifdef GST_EXT_ASYNC_DEV
580 fprintf(fp, "GST_EXT_ASYNC_DEV\n");
582 #ifdef GST_EXT_AV_RECORDING
583 fprintf(fp, "GST_EXT_AV_RECORDING\n");
585 #ifdef GST_EXT_SWITCH_CAMERA
586 fprintf(fp, "GST_EXT_SWITCH_CAMERA\n");
595 void gst_ta_accum_show_result(int direction)
607 case MMTA_SHOW_STDOUT: fp = stdout; break;
608 case MMTA_SHOW_STDERR: fp = stderr; break;
611 fp = fopen("/tmp/gst-ta.log", "wt");
618 __print_some_info(fp);
621 #ifdef GST_EXT_TA_UNIT_MSEC
622 sprintf(format, "[%%3d] %%-%ds | \ttotal : %%4ld\tcalls : %%3ld\tavg : %%4ld\tmin : %%4ld\tmax : %%4ld\tstart : %%4lu\tend : %%4lu\tunpair : %%3ld\n", g_accum_longest_name);
623 fprintf(fp, "BEGIN RESULT ACCUM============================ : NumOfItems : %d, unit(msec)\n", g_accum_index);
625 snprintf(format, sizeof(format)-1, "[%%3d] %%-%ds | \ttotal : %%ld\tcalls : %%ld\tavg : %%ld\tmin : %%ld\tmax : %%ld\tstart : %%lu\tend : %%lu\tunpair : %%ld\n", g_accum_longest_name);
626 fprintf(fp, "BEGIN RESULT ACCUM============================ : NumOfItems : %d, unit(usec)\n", g_accum_index);
629 for ( i = 0; i < g_accum_index; i++ )
631 /* prevent 'devide by zero' error */
632 if (g_accums[i]->num_calls == 0)
633 g_accums[i]->num_calls = 1;
639 g_accums[i]->elapsed_accum,
640 g_accums[i]->num_calls,
641 (g_accums[i]->elapsed_accum == 0)?0:(int)(g_accums[i]->elapsed_accum / g_accums[i]->num_calls),
642 g_accums[i]->elapsed_min,
643 g_accums[i]->elapsed_max,
644 g_accums[i]->first_start - g_accum_first_time,
645 g_accums[i]->last_end - g_accum_first_time,
646 g_accums[i]->num_unpair );
648 fprintf(fp, "END RESULT ACCUM ============================\n");
650 if ( direction == MMTA_SHOW_FILE )