summaryrefslogtreecommitdiffstats
path: root/domx/domx/profiling/src/profile.c
blob: bc050b7e07b86fd3962e9c0ebd420fc1e6f546d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
 * Copyright (c) 2010, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 *  @file  profile.c
 *         This file contains methods to profile DOMX
 *
 *  @path ...\hardware\ti\domx\domx\profiling\inc
 *
 *  @rev 1.0
 */

/******************************************************************
 *   INCLUDE FILES
 ******************************************************************/
/* ----- system and platform files ----------------------------*/
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef _Android
#include <cutils/properties.h>
#endif

#include <OMX_Types.h>
#include <OMX_Component.h>

/*-------program files ----------------------------------------*/
#include "omx_rpc_utils.h"
#include "omx_proxy_common.h"
#include "profile.h"


/******************************************************************
 *   DEFINES - CONSTANTS
 ******************************************************************/
/* Events that can be dynamically enabled */
enum KPI_STATUS {
	KPI_BUFFER_EVENTS = 1
};

/* OMX buffer events per component */
typedef struct {
	OMX_HANDLETYPE hComponent;
	OMX_U32 count_ftb;
	OMX_U32 count_fbd;
	OMX_U32 count_etb;
	OMX_U32 count_ebd;
	char name[50];
} kpi_omx_component;

/* we trace up to MAX_OMX_COMP components */
#define MAX_OMX_COMP 8


/***************************************************************
 * kpi_omx_monitor
 * -------------------------------------------------------------
 * Contains up to 8 components data
 *
 ***************************************************************/
kpi_omx_component kpi_omx_monitor[MAX_OMX_COMP]; /* we trace up to MAX_OMX_COMP components */
OMX_U32 kpi_omx_monitor_cnt = 0; /* no component yet */
unsigned int kpi_status = 0;


/* ===========================================================================*/
/**
 * @name KPI_GetTime()
 * @brief Compute time since boot to timestamp events
 * @param void
 * @return OMX_U64 = time since boot in us
 * @sa TBD
 *
 */
/* ===========================================================================*/
OMX_U64 KPI_GetTime(void)
{
	struct timespec tp;

	clock_gettime(CLOCK_MONOTONIC, &tp);
	return (tp.tv_sec * 1000000 + tp.tv_nsec / 1000);
}

/* ===========================================================================*/
/**
 * @name KPI_OmxCompKpiUpdateStatus()
 * @brief Update dynamic activation of traces
 * @param void
 * @return void
 * @sa TBD
 *
 */
/* ===========================================================================*/
void KPI_OmxCompKpiUpdateStatus(void)
{
        char *val = getenv("DEBUG_DOMX_KPI_STATUS");

        if (val)
        {
                kpi_status = strtol(val, NULL, 0);
        }
#ifdef _Android
        else
        {
                char value[PROPERTY_VALUE_MAX];
                int val;

                property_get("debug.domx.kpi_status", value, "0");
                val = atoi(value);
                if (val >= 0)
                        kpi_status = val;
        }
#endif
}

/* ===========================================================================*/
/**
 * @name KPI_OmxCompInit()
 * @brief Prepare monitoring structure for new component starting
 * @param void
 * @return void
 * @sa TBD
 *
 */
/* ===========================================================================*/
void KPI_OmxCompInit(OMX_HANDLETYPE hComponent)
{
	OMX_VERSIONTYPE nVersionComp;
	OMX_VERSIONTYPE nVersionSpec;
	OMX_UUIDTYPE    compUUID;
	char compName[OMX_MAX_STRINGNAME_SIZE];
	char* p;
	OMX_U32 omx_cnt;
	struct timespec tp;

	/* Check if some profiling events have been enabled/disabled */
	KPI_OmxCompKpiUpdateStatus();

	if ( !(kpi_status & KPI_BUFFER_EVENTS) )
		return;

	/* First init: clear kpi_omx_monitor components */
	if( kpi_omx_monitor_cnt == 0) {
		for (omx_cnt = 0; omx_cnt < MAX_OMX_COMP; omx_cnt++) {
			/*clear handler registry */
			kpi_omx_monitor[omx_cnt].hComponent = 0;
		}
	}

	/* find an empty monitoring structure */
	for( omx_cnt = 0; omx_cnt < MAX_OMX_COMP;  omx_cnt++ ) {
		if( kpi_omx_monitor[omx_cnt].hComponent == 0 ) break;
	}

	/* too omany components started, do not monitor */
	if( omx_cnt >= MAX_OMX_COMP) return;

	/* current comp num and update */
	kpi_omx_monitor_cnt++;

	/* register the component handle */
	kpi_omx_monitor[omx_cnt].hComponent = hComponent;

	/* reset event counts */
	kpi_omx_monitor[omx_cnt].count_ftb = 0;
	kpi_omx_monitor[omx_cnt].count_fbd = 0;
	kpi_omx_monitor[omx_cnt].count_etb = 0;
	kpi_omx_monitor[omx_cnt].count_ebd = 0;

	/* register the component name */
	((OMX_COMPONENTTYPE*) hComponent)->GetComponentVersion(hComponent, compName, &nVersionComp, &nVersionSpec, &compUUID);

	/* get the end of the string compName... */
	p = compName + strlen( compName ) - 1;
	while( (*p != '.' ) && (p != compName) ) p--;
	strncpy(kpi_omx_monitor[omx_cnt].name, p + 1, 6);

	/* trace component init */
	DOMX_PROF("<KPI> OMX %-6s Init %-8lld", kpi_omx_monitor[omx_cnt].name, KPI_GetTime());

	return;
}

/* ===========================================================================*/
/**
 * @name KPI_OmxCompDeinit()
 * @brief Reset monitoring structure for component stopping
 * @param void
 * @return void
 * @sa TBD
 *
 */
/* ===========================================================================*/
void KPI_OmxCompDeinit( OMX_HANDLETYPE hComponent)
{
	OMX_U32 omx_cnt;

	if ( !(kpi_status & KPI_BUFFER_EVENTS) )
		return;

	if( kpi_omx_monitor_cnt == 0) return;

	/* identify the component from the registry */
	for( omx_cnt = 0; omx_cnt < MAX_OMX_COMP;  omx_cnt++ ) {
		if( kpi_omx_monitor[omx_cnt].hComponent == hComponent ) break;
	}

	/* trace component init */
	DOMX_PROF( "<KPI> OMX %-6s Deinit %-8lld", kpi_omx_monitor[omx_cnt].name, KPI_GetTime());

	/* unregister the component */
	kpi_omx_monitor[omx_cnt].hComponent = 0;

	kpi_omx_monitor_cnt--;

	return;
}

/* ===========================================================================*/
/**
 * @name KPI_OmxCompBufferEvent()
 * @brief Trace FTB/ETB/FBD/EBD events
 * @param void
 * @return void
 * @sa TBD
 *
 */
/* ===========================================================================*/
void KPI_OmxCompBufferEvent(enum KPI_BUFFER_EVENT event, OMX_HANDLETYPE hComponent, PROXY_BUFFER_INFO* pBuffer)
{
        OMX_U32 omx_cnt;

	if ( !(kpi_status & KPI_BUFFER_EVENTS) )
		return;

        if (kpi_omx_monitor_cnt == 0) return;

        /* identify the component from the registry */
        for (omx_cnt = 0; omx_cnt < MAX_OMX_COMP;  omx_cnt++) {
                if( kpi_omx_monitor[omx_cnt].hComponent == hComponent ) break;
        }

        /* Update counts and trace the event */
        if( omx_cnt < MAX_OMX_COMP ) {
                /* trace the event, we trace remote address to correlate to Ducati trace */
		switch(event) {
			case KPI_BUFFER_ETB:
				DOMX_PROF("ETB %-6s %-4u %-8lld x%-8x", kpi_omx_monitor[omx_cnt].name, \
					(unsigned int)++kpi_omx_monitor[omx_cnt].count_etb, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote);
			break;
			case KPI_BUFFER_FTB:
				DOMX_PROF("FTB %-6s %-4u %-8lld x%-8x", kpi_omx_monitor[omx_cnt].name, \
					(unsigned int)++kpi_omx_monitor[omx_cnt].count_ftb, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote);
			break;
			case KPI_BUFFER_EBD:
				DOMX_PROF("EBD %-6s %-4u %-8lld x%-8x", kpi_omx_monitor[omx_cnt].name, \
					(unsigned int)++kpi_omx_monitor[omx_cnt].count_ebd, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote);
			break;
			/* we add timestamp metadata because this is a unique identifier of buffer among all SW layers */
			case KPI_BUFFER_FBD:
		                DOMX_PROF("FBD %-6s %-4u %-8lld x%-8x %lld", kpi_omx_monitor[omx_cnt].name, \
					(unsigned int)++kpi_omx_monitor[omx_cnt].count_fbd, KPI_GetTime(), (unsigned int)pBuffer->pBufHeaderRemote, pBuffer->pBufHeader->nTimeStamp);
			break;

		}
        }

        return;
}