Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 2010, Texas Instruments Incorporated
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * *  Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *
     12  * *  Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * *  Neither the name of Texas Instruments Incorporated nor the names of
     17  *    its contributors may be used to endorse or promote products derived
     18  *    from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /**
     34  *  @file  profile.c
     35  *         This file contains methods to profile DOMX
     36  *
     37  *  @path ...\hardware\ti\domx\domx\profiling\inc
     38  *
     39  *  @rev 1.0
     40  */
     41 
     42 /******************************************************************
     43  *   INCLUDE FILES
     44  ******************************************************************/
     45 /* ----- system and platform files ----------------------------*/
     46 #include <stdlib.h>
     47 #include <string.h>
     48 #include <time.h>
     49 
     50 #ifdef _Android
     51 #include <cutils/properties.h>
     52 #endif
     53 
     54 #include <OMX_Types.h>
     55 #include <OMX_Component.h>
     56 
     57 /*-------program files ----------------------------------------*/
     58 #include "omx_rpc_utils.h"
     59 #include "omx_proxy_common.h"
     60 #include "profile.h"
     61 
     62 
     63 /******************************************************************
     64  *   DEFINES - CONSTANTS
     65  ******************************************************************/
     66 /* Events that can be dynamically enabled */
     67 enum KPI_STATUS {
     68 	KPI_BUFFER_EVENTS = 1
     69 };
     70 
     71 /* OMX buffer events per component */
     72 typedef struct {
     73 	OMX_HANDLETYPE hComponent;
     74 	OMX_U32 count_ftb;
     75 	OMX_U32 count_fbd;
     76 	OMX_U32 count_etb;
     77 	OMX_U32 count_ebd;
     78 	char name[50];
     79 } kpi_omx_component;
     80 
     81 /* we trace up to MAX_OMX_COMP components */
     82 #define MAX_OMX_COMP 8
     83 
     84 
     85 /***************************************************************
     86  * kpi_omx_monitor
     87  * -------------------------------------------------------------
     88  * Contains up to 8 components data
     89  *
     90  ***************************************************************/
     91 kpi_omx_component kpi_omx_monitor[MAX_OMX_COMP]; /* we trace up to MAX_OMX_COMP components */
     92 OMX_U32 kpi_omx_monitor_cnt = 0; /* no component yet */
     93 unsigned int kpi_status = 0;
     94 
     95 
     96 /* ===========================================================================*/
     97 /**
     98  * @name KPI_GetTime()
     99  * @brief Compute time since boot to timestamp events
    100  * @param void
    101  * @return OMX_U64 = time since boot in us
    102  * @sa TBD
    103  *
    104  */
    105 /* ===========================================================================*/
    106 OMX_U64 KPI_GetTime(void)
    107 {
    108 	struct timespec tp;
    109 
    110 	clock_gettime(CLOCK_MONOTONIC, &tp);
    111 	return (tp.tv_sec * 1000000 + tp.tv_nsec / 1000);
    112 }
    113 
    114 /* ===========================================================================*/
    115 /**
    116  * @name KPI_OmxCompKpiUpdateStatus()
    117  * @brief Update dynamic activation of traces
    118  * @param void
    119  * @return void
    120  * @sa TBD
    121  *
    122  */
    123 /* ===========================================================================*/
    124 void KPI_OmxCompKpiUpdateStatus(void)
    125 {
    126         char *val = getenv("DEBUG_DOMX_KPI_STATUS");
    127 
    128         if (val)
    129         {
    130                 kpi_status = strtol(val, NULL, 0);
    131         }
    132 #ifdef _Android
    133         else
    134         {
    135                 char value[PROPERTY_VALUE_MAX];
    136                 int val;
    137 
    138                 property_get("debug.domx.kpi_status", value, "0");
    139                 val = atoi(value);
    140                 if (val >= 0)
    141                         kpi_status = val;
    142         }
    143 #endif
    144 }
    145 
    146 /* ===========================================================================*/
    147 /**
    148  * @name KPI_OmxCompInit()
    149  * @brief Prepare monitoring structure for new component starting
    150  * @param void
    151  * @return void
    152  * @sa TBD
    153  *
    154  */
    155 /* ===========================================================================*/
    156 void KPI_OmxCompInit(OMX_HANDLETYPE hComponent)
    157 {
    158 	OMX_VERSIONTYPE nVersionComp;
    159 	OMX_VERSIONTYPE nVersionSpec;
    160 	OMX_UUIDTYPE    compUUID;
    161 	char compName[OMX_MAX_STRINGNAME_SIZE];
    162 	char* p;
    163 	OMX_U32 omx_cnt;
    164 	struct timespec tp;
    165 
    166 	/* Check if some profiling events have been enabled/disabled */
    167 	KPI_OmxCompKpiUpdateStatus();
    168 
    169 	if ( !(kpi_status & KPI_BUFFER_EVENTS) )
    170 		return;
    171 
    172 	/* First init: clear kpi_omx_monitor components */
    173 	if( kpi_omx_monitor_cnt == 0) {
    174 		for (omx_cnt = 0; omx_cnt < MAX_OMX_COMP; omx_cnt++) {
    175 			/*clear handler registry */
    176 			kpi_omx_monitor[omx_cnt].hComponent = 0;
    177 		}
    178 	}
    179 
    180 	/* find an empty monitoring structure */
    181 	for( omx_cnt = 0; omx_cnt < MAX_OMX_COMP;  omx_cnt++ ) {
    182 		if( kpi_omx_monitor[omx_cnt].hComponent == 0 ) break;
    183 	}
    184 
    185 	/* too omany components started, do not monitor */
    186 	if( omx_cnt >= MAX_OMX_COMP) return;
    187 
    188 	/* current comp num and update */
    189 	kpi_omx_monitor_cnt++;
    190 
    191 	/* register the component handle */
    192 	kpi_omx_monitor[omx_cnt].hComponent = hComponent;
    193 
    194 	/* reset event counts */
    195 	kpi_omx_monitor[omx_cnt].count_ftb = 0;
    196 	kpi_omx_monitor[omx_cnt].count_fbd = 0;
    197 	kpi_omx_monitor[omx_cnt].count_etb = 0;
    198 	kpi_omx_monitor[omx_cnt].count_ebd = 0;
    199 
    200 	/* register the component name */
    201 	((OMX_COMPONENTTYPE*) hComponent)->GetComponentVersion(hComponent, compName, &nVersionComp, &nVersionSpec, &compUUID);
    202 
    203 	/* get the end of the string compName... */
    204 	p = compName + strlen( compName ) - 1;
    205 	while( (*p != '.' ) && (p != compName) ) p--;
    206 	strncpy(kpi_omx_monitor[omx_cnt].name, p + 1, 6);
    207 
    208 	/* trace component init */
    209 	DOMX_PROF("<KPI> OMX %-6s Init %-8lld", kpi_omx_monitor[omx_cnt].name, KPI_GetTime());
    210 
    211 	return;
    212 }
    213 
    214 /* ===========================================================================*/
    215 /**
    216  * @name KPI_OmxCompDeinit()
    217  * @brief Reset monitoring structure for component stopping
    218  * @param void
    219  * @return void
    220  * @sa TBD
    221  *
    222  */
    223 /* ===========================================================================*/
    224 void KPI_OmxCompDeinit( OMX_HANDLETYPE hComponent)
    225 {
    226 	OMX_U32 omx_cnt;
    227 
    228 	if ( !(kpi_status & KPI_BUFFER_EVENTS) )
    229 		return;
    230 
    231 	if( kpi_omx_monitor_cnt == 0) return;
    232 
    233 	/* identify the component from the registry */
    234 	for( omx_cnt = 0; omx_cnt < MAX_OMX_COMP;  omx_cnt++ ) {
    235 		if( kpi_omx_monitor[omx_cnt].hComponent == hComponent ) break;
    236 	}
    237 
    238 	/* trace component init */
    239 	DOMX_PROF( "<KPI> OMX %-6s Deinit %-8lld", kpi_omx_monitor[omx_cnt].name, KPI_GetTime());
    240 
    241 	/* unregister the component */
    242 	kpi_omx_monitor[omx_cnt].hComponent = 0;
    243 
    244 	kpi_omx_monitor_cnt--;
    245 
    246 	return;
    247 }
    248 
    249 /* ===========================================================================*/
    250 /**
    251  * @name KPI_OmxCompBufferEvent()
    252  * @brief Trace FTB/ETB/FBD/EBD events
    253  * @param void
    254  * @return void
    255  * @sa TBD
    256  *
    257  */
    258 /* ===========================================================================*/
    259 void KPI_OmxCompBufferEvent(enum KPI_BUFFER_EVENT event, OMX_HANDLETYPE hComponent, PROXY_BUFFER_INFO* pBuffer)
    260 {
    261         OMX_U32 omx_cnt;
    262 
    263 	if ( !(kpi_status & KPI_BUFFER_EVENTS) )
    264 		return;
    265 
    266         if (kpi_omx_monitor_cnt == 0) return;
    267 
    268         /* identify the component from the registry */
    269         for (omx_cnt = 0; omx_cnt < MAX_OMX_COMP;  omx_cnt++) {
    270                 if( kpi_omx_monitor[omx_cnt].hComponent == hComponent ) break;
    271         }
    272 
    273         /* Update counts and trace the event */
    274         if( omx_cnt < MAX_OMX_COMP ) {
    275                 /* trace the event, we trace remote address to correlate to Ducati trace */
    276 		switch(event) {
    277 			case KPI_BUFFER_ETB:
    278 				DOMX_PROF("ETB %-6s %-4u %-8lld x%-8x", kpi_omx_monitor[omx_cnt].name, \
    279 					(unsigned int)++kpi_omx_monitor[omx_cnt].count_etb, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote);
    280 			break;
    281 			case KPI_BUFFER_FTB:
    282 				DOMX_PROF("FTB %-6s %-4u %-8lld x%-8x", kpi_omx_monitor[omx_cnt].name, \
    283 					(unsigned int)++kpi_omx_monitor[omx_cnt].count_ftb, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote);
    284 			break;
    285 			case KPI_BUFFER_EBD:
    286 				DOMX_PROF("EBD %-6s %-4u %-8lld x%-8x", kpi_omx_monitor[omx_cnt].name, \
    287 					(unsigned int)++kpi_omx_monitor[omx_cnt].count_ebd, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote);
    288 			break;
    289 			/* we add timestamp metadata because this is a unique identifier of buffer among all SW layers */
    290 			case KPI_BUFFER_FBD:
    291 		                DOMX_PROF("FBD %-6s %-4u %-8lld x%-8x %lld", kpi_omx_monitor[omx_cnt].name, \
    292 					(unsigned int)++kpi_omx_monitor[omx_cnt].count_fbd, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote, pBuffer->pBufHeader->nTimeStamp);
    293 			break;
    294 
    295 		}
    296         }
    297 
    298         return;
    299 }
    300