1 
2 /*
3  * Copyright (C) Texas Instruments - http://www.ti.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 /* This headerdescribes the external PERF interface */
22 #ifndef __PERF_H__
23 #define __PERF_H__
24 
25 /* global flag */
26 #ifdef __PERF_INSTRUMENTATION__
27 
28 /** Compile-tempTime configuration options
29 *
30 *   In order to facilitate more flexible configuration options,
31 *   yet maintain run-tempTime performance, we allow the following
32 *   configuration options:
33 *
34 *   __PERF_CUSTOMIZABLE__
35 *
36 *   If enabled, we allow customized implementation of the
37 *   performance interface, e.g. unbuffered debug prints to find
38 *   the point of a program crash. For more information on the
39 *   specific features supported, see perf_custom.h.
40 *
41 *   If disabled, all instrumentation calls are hard-coded to be
42 *   logged into a logging buffer.
43 * */
44 
45 #if defined(__PERF_LOG_LOCATION__)
46     #define __PERF_Location(hObject) \
47         __PERF_FN(Location) (hObject,__FILE__,__LINE__,__func__);
48 #elif defined(__PERF_LOCATE__)
49     #define __PERF_Location(hObject) \
50         fprintf(stderr,"PERF in [%s:%d func:%s]:",__FILE__,__LINE__,__func__);
51 #else
52     #define __PERF_Location(hObject)
53 #endif
54 
55 #ifdef __PERF_CUSTOMIZABLE__
56     #define __PERF_FN(a) __PERF_CUSTOM_##a
57 #else
58     #define __PERF_FN(a) __PERF_LOG_##a
59 #endif
60 
61 /*=============================================================================
62     Overall API methodology.
63 
64     Since this is an instrumentation API, other than the create call, no
65     other methods return any value, so there is no error checking
66     requirements.
67 
68     If the create call encounters any errors, or if the instrumentation is run-
69     tempTime disabled, it will return NULL.  All other API-s must handle a NULL
70     argument, and will do nothing in such case.
71 =============================================================================*/
72 
73 /* Four CC calculations from characters and string */
74 
75 #define PERF_FOURCC(a,b,c,d)                   \
76     ( ((((unsigned long) (a)) & 0xFF) << 24) | \
77       ((((unsigned long) (b)) & 0xFF) << 16) | \
78       ((((unsigned long) (c)) & 0xFF) << 8)  | \
79        (((unsigned long) (d)) & 0xFF) )
80 
81 #define PERF_FOURS(id) \
82       PERF_FOURCC((id)[0], (id)[1], (id)[2], (id)[3])
83 
84 #define PERF_FOUR_CHARS(i) \
85       (char) (((i) >> 24) & 0xFF), (char) (((i) >> 16) & 0xFF), \
86       (char) (((i) >> 8)  & 0xFF), (char) ((i) & 0xFF)
87 
88 #define PREF(a,b) ((a) ? (a)->b : 0)
89 
90 /*=============================================================================
91     ENUMERATIONS
92 =============================================================================*/
93 
94 /*-----------------------------------------------------------------------------
95     PERF_BOUNDARYTYPE
96 
97     The phase of execution for the Boundary callback
98 -----------------------------------------------------------------------------*/
99 typedef enum PERF_BOUNDARYTYPE
100 {
101     /* UC phase boundary type */
102     PERF_BoundaryStart      = 0,
103     PERF_BoundaryComplete   = 0x10000,
104 
105     /* UC phase type */
106     PERF_BoundarySetup = 1,   /* UC initialization */
107     PERF_BoundaryCleanup,     /* UC cleanup */
108     PERF_BoundarySteadyState, /* UC is in 'steady state' - optional */
109 
110     PERF_BoundaryMax,
111     PERF_BoundaryMask   = 3,
112 } PERF_BOUNDARYTYPE;
113 
114 #ifdef __PERF_PRINT_C__
115 
116 char const * const PERF_BoundaryTypes[] = {"NONE", "Setup", "Cleanup", "Steady"};
117 
118 #endif
119 
120 #define PERF_IsComplete(x) ((x) & PERF_BoundaryComplete)
121 #define PERF_IsStarted(x)  (!PERF_IsComplete(x))
122 
123 /*-----------------------------------------------------------------------------
124     PERF_MODULETYPE
125 
126     Type of module when creating the component, or when specifying source
127     or destination of buffer transfers and/or commands
128 -----------------------------------------------------------------------------*/
129 
130 /* These flags are also used for the LOG commands */
131 #define PERF_FlagSending     0x10000000ul   /* This is used for LOG */
132 #define PERF_FlagSent        0x30000000ul   /* This is used for LOG */
133 #define PERF_FlagRequesting  0x20000000ul   /* This is used for LOG */
134 #define PERF_FlagReceived    0x00000000ul   /* This is used for LOG */
135 #define PERF_FlagSendFlags   0x30000000ul
136 #define PERF_FlagXfering     0x40000000ul   /* This is used for LOG */
137                                             /* = Received + Sending */
138 #define PERF_FlagFrame       0x08000000ul
139 #define PERF_FlagBuffer      0x00000000ul
140 #define PERF_FlagMultiple    0x80000000ul
141 #define PERF_FlagSingle      0x00000000ul
142 
143 #define PERF_GetSendRecv(x) ((x) & PERF_FlagSent)
144 #define PERF_GetXferSendRecv(x) ((x) & (PERF_FlagSendFlags | PERF_FlagXfering))
145 #define PERF_GetFrameBuffer(x)     PERF_IsFrame(x)
146 #define PERF_GetMultipleSingle(x)  PERF_IsMultiple(x)
147 
148 #define PERF_IsFrame(x)     ((x) & PERF_FlagFrame)
149 #define PERF_IsBuffer(x)    (!PERF_IsFrame(x))
150 #define PERF_IsSending(x)   ((x) & PERF_FlagSending)
151 #define PERF_IsReceived(x)  (!PERF_IsSending(x))
152 #define PERF_IsXfering(x)   ((x) & PERF_FlagXfering)
153 #define PERF_IsMultiple(x)  ((x) & PERF_FlagMultiple)
154 #define PERF_IsSingle(x)    (!PERF_IsMultiple(x))
155 
156 typedef enum PERF_MODULETYPE
157 {
158     PERF_ModuleApplication,  /* application */
159     PERF_ModuleSystem,       /* system components */
160     PERF_ModuleService,      /* service or server */
161     PERF_ModuleHLMM,         /* high-level multimedia, e.g. MMF */
162     PERF_ModuleLLMM,         /* low-level multimedia, e.g. MDF, OMX */
163     PERF_ModuleComponent,    /* multimedia component */
164     PERF_ModuleCommonLayer,  /* common layer */
165     PERF_ModuleSocketNode,   /* socket-node (e.g. on DSP) */
166     PERF_ModuleAlgorithm,    /* algorithm (for possible future needs) */
167     PERF_ModuleHardware,     /* hardware (e.g. speaker, microphone) */
168     PERF_ModuleMemory,       /* memory or unspecified modules */
169     PERF_ModuleMemoryMap,    /* memory mapping */
170     PERF_ModuleMax,
171     PERF_ModuleBits = 4,
172     PERF_ModuleMask = (1 << PERF_ModuleBits) - 1,
173 
174     /* module functional types used for selectively enabling instrumentation */
175     PERF_ModuleDomains     = 1 << (1 << PERF_ModuleBits),
176     PERF_ModuleAudioDecode = PERF_ModuleDomains,
177     PERF_ModuleAudioEncode = PERF_ModuleAudioDecode << 1,
178     PERF_ModuleVideoDecode = PERF_ModuleAudioEncode << 1,
179     PERF_ModuleVideoEncode = PERF_ModuleVideoDecode << 1,
180     PERF_ModuleImageDecode = PERF_ModuleVideoEncode << 1,
181     PERF_ModuleImageEncode = PERF_ModuleImageDecode << 1,
182 } PERF_MODULETYPE;
183 
184 #ifdef __PERF_PRINT_C__
185 
186 char const * const PERF_ModuleTypes[] = {
187     "Application", "System",    "Service",     "HLMM",
188     "LLMM",        "Component", "CommonLayer", "SocketNode",
189     "Algorithm",   "Hardware",  "Memory",      "MemoryMap"
190 };
191 
192 #endif
193 
194 /*-----------------------------------------------------------------------------
195     PERF_SYNCOPTYPE
196 
197     Type of module phase of execution for the cbBoundary callback
198 -----------------------------------------------------------------------------*/
199 typedef enum PERF_SYNCOPTYPE
200 {
201     PERF_SyncOpNone,
202     PERF_SyncOpDropVideoFrame,   /* drop a video frame */
203     PERF_SyncOpMax,
204 } PERF_SYNCOPTYPE;
205 
206 #ifdef __PERF_PRINT_C__
207 
208 char const *PERF_SyncOpTypes[] = {
209     "none", "drop_video_frame"
210 };
211 
212 #endif
213 
214 /*-----------------------------------------------------------------------------
215     PERF_COMMANDTYPE
216 
217     PERF commands
218 -----------------------------------------------------------------------------*/
219 typedef enum PERF_COMMANDTYPE
220 {
221     PERF_CommandMax,
222     PERF_CommandStatus = 0x10000000,
223 } PERF_COMMANDTYPE;
224 
225 #ifdef __PERF_PRINT_C__
226 
227 char const *PERF_CommandTypes[] = {
228     "none"
229 };
230 
231 #endif
232 
233 
234 /*=============================================================================
235     CREATION INTERFACE
236 =============================================================================*/
237 typedef struct PERF_OBJTYPE *PERF_OBJHANDLE;
238 
239 /** PERF_Create method is the is used to create an
240 *   instrumentation object for a component.
241 *
242 *   NOTE: It's arguments may depend on the operating system, as
243 *   the PERF object may need access to system resource
244 *   (terminal, file system).  For now, we assume that all
245 *   interfaces are accessible from system calls.
246 *
247 *   This operation may include allocating resources from the
248 *   system, to create any structures required for managing the
249 *   data collected during instrumentation, but our aim is to
250 *   have these resources be minimal.
251 *
252 *   Most options are run-tempTime configurable.  See perf_config.h
253 *   for such options.
254 *
255 *   In case of error - or if performance instrumentation is
256 *   run-tempTime disabled, PERF_Create will return a NULL handle,
257 *   and all resource allocations will be undone.
258 *
259 *   @param ulComponent
260 *       FourCC component ID.
261 *   @param eModule
262 *       ModuleType.
263 *   @return hObject
264 *       Handle to the instrumentation object.
265  */
266 
267 PERF_OBJHANDLE PERF_Create(
268                           unsigned long ulComponentName,
269                           PERF_MODULETYPE eModule);
270 
271 /** The PERF_Done method is called at the end of the component
272 *   life cycle.
273 *   @param hObject
274 *       Handle to the PERF object.  This must be an lvalue, as
275 *       it will be deleted and set to NULL upon return.
276 * */
277 #define PERF_Done(           \
278         hObject)             \
279     do {                     \
280     __PERF_Location(hObject) \
281     __PERF_Done(hObject);    \
282     } while (0)
283 
284 
285 /*=============================================================================
286     INSTRUMENTATION INTERFACE
287 =============================================================================*/
288 
289 /** The PERF_Boundary callback must be called by the component
290 *   at specific phases of the component.
291 *   @param hObject
292 *       Handle to the PERF object.
293 *   @param eBoundary
294 *       Boundary (phase) that is reached by the application.
295 * */
296 
297 #define PERF_Boundary(       \
298         hObject,             \
299         eBoundary)           \
300     do {                     \
301     __PERF_Location(hObject) \
302     __PERF_FN(Boundary)(hObject, eBoundary); \
303     } while (0)
304 
305 /** The PERF_SendingBuffer(s) and PERF_SendingFrame(s) method is
306 *   used to mark when a buffer (or frame) is to be sent to
307 *   another module.
308 *
309 *   @param hObject
310 *       Handle to the PERF object.
311 *   @param ulAddress or ulAddress1 and ulAddress2
312 *       Buffer (or frame) address(es).
313 *   @param ulSize
314 *       size of buffer(s) that is sent regardless if it is sent
315 *       by pointer exchange or memory copy.
316 *   @param eModuleTo
317 *       Type of module that is receiving the data.
318 * */
319 #define PERF_SendingBuffer(                                             \
320         hObject,                                                        \
321         ulAddress,                                                      \
322         ulSize,                                                         \
323         eModuleTo)                                                      \
324   do {                                                                  \
325   __PERF_Location(hObject)                                              \
326   __PERF_FN(Buffer)(hObject,                                            \
327                     PERF_FlagSending, PERF_FlagSingle, PERF_FlagBuffer, \
328                     ulAddress, NULL, ulSize, eModuleTo, 0);             \
329   } while(0)
330 
331 #define PERF_SendingFrame(                                             \
332         hObject,                                                       \
333         ulAddress,                                                     \
334         ulSize,                                                        \
335         eModuleTo)                                                     \
336   do {                                                                 \
337   __PERF_Location(hObject)                                             \
338   __PERF_FN(Buffer)(hObject,                                           \
339                     PERF_FlagSending, PERF_FlagSingle, PERF_FlagFrame, \
340                     ulAddress, NULL, ulSize, eModuleTo, 0);            \
341   } while (0)
342 
343 #define PERF_SendingBuffers(                                              \
344         hObject,                                                          \
345         ulAddress1,                                                       \
346         ulAddress2,                                                       \
347         ulSize,                                                           \
348         eModuleTo)                                                        \
349   do {                                                                    \
350   __PERF_Location(hObject)                                                \
351   __PERF_FN(Buffer)(hObject,                                              \
352                     PERF_FlagSending, PERF_FlagMultiple, PERF_FlagBuffer, \
353                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);        \
354   } while (0)
355 
356 #define PERF_SendingFrames(                                              \
357         hObject,                                                         \
358         ulAddress1,                                                      \
359         ulAddress2,                                                      \
360         ulSize,                                                          \
361         eModuleTo)                                                       \
362   do {                                                                   \
363   __PERF_Location(hObject)                                               \
364   __PERF_FN(Buffer)(hObject,                                             \
365                     PERF_FlagSending, PERF_FlagMultiple, PERF_FlagFrame, \
366                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);       \
367   } while (0)
368 
369 /** The PERF_SendingCommand method is used to mark when a
370 *   command is to be sent to another module.
371 *
372 *   @param hObject
373 *       Handle to the PERF object.
374 *   @param ulCommand
375 *       Command.
376 *   @param eModuleTo
377 *       Type of module that is receiving the data.
378 * */
379 #define PERF_SendingCommand(  \
380         hObject,              \
381         ulCommand,            \
382         ulArgument,           \
383         eModuleTo)            \
384   do {                        \
385   __PERF_Location(hObject)    \
386   __PERF_FN(Command)(hObject, \
387                      PERF_FlagSending, ulCommand, ulArgument, eModuleTo); \
388   } while (0)
389 
390 /** The PERF_SentBuffer(s) and PERF_SentFrame(s) method is
391 *   used to mark when a buffer (or frame) has been sent to
392 *   another module.
393 *
394 *   @param hObject
395 *       Handle to the PERF object.
396 *   @param ulAddress or ulAddress1 and ulAddress2
397 *       Buffer (or frame) address(es).
398 *   @param ulSize
399 *       size of buffer(s) that is sent regardless if it is sent
400 *       by pointer exchange or memory copy.
401 *   @param eModuleTo
402 *       Type of module that is receiving the data.
403 * */
404 #define PERF_SentBuffer(                                             \
405         hObject,                                                     \
406         ulAddress,                                                   \
407         ulSize,                                                      \
408         eModuleTo)                                                   \
409   do {                                                               \
410   __PERF_Location(hObject)                                           \
411   __PERF_FN(Buffer)(hObject,                                         \
412                     PERF_FlagSent, PERF_FlagSingle, PERF_FlagBuffer, \
413                     ulAddress, NULL, ulSize, eModuleTo, 0);          \
414   } while(0)
415 
416 #define PERF_SentFrame(                                             \
417         hObject,                                                    \
418         ulAddress,                                                  \
419         ulSize,                                                     \
420         eModuleTo)                                                  \
421   do {                                                              \
422   __PERF_Location(hObject)                                          \
423   __PERF_FN(Buffer)(hObject,                                        \
424                     PERF_FlagSent, PERF_FlagSingle, PERF_FlagFrame, \
425                     ulAddress, NULL, ulSize, eModuleTo, 0);         \
426   } while (0)
427 
428 #define PERF_SentBuffers(                                              \
429         hObject,                                                       \
430         ulAddress1,                                                    \
431         ulAddress2,                                                    \
432         ulSize,                                                        \
433         eModuleTo)                                                     \
434   do {                                                                 \
435   __PERF_Location(hObject)                                             \
436   __PERF_FN(Buffer)(hObject,                                           \
437                     PERF_FlagSent, PERF_FlagMultiple, PERF_FlagBuffer, \
438                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);     \
439   } while (0)
440 
441 #define PERF_SentFrames(                                              \
442         hObject,                                                      \
443         ulAddress1,                                                   \
444         ulAddress2,                                                   \
445         ulSize,                                                       \
446         eModuleTo)                                                    \
447   do {                                                                \
448   __PERF_Location(hObject)                                            \
449   __PERF_FN(Buffer)(hObject,                                          \
450                     PERF_FlagSent, PERF_FlagMultiple, PERF_FlagFrame, \
451                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);    \
452   } while (0)
453 
454 /** The PERF_SentCommand method is used to mark when a
455 *   command has been sent to another module.
456 *
457 *   @param hObject
458 *       Handle to the PERF object.
459 *   @param ulCommand
460 *       Command.
461 *   @param eModuleTo
462 *       Type of module that is receiving the data.
463 * */
464 #define PERF_SentCommand(     \
465         hObject,              \
466         ulCommand,            \
467         ulArgument,           \
468         eModuleTo)            \
469   do {                        \
470   __PERF_Location(hObject)    \
471   __PERF_FN(Command)(hObject, \
472                      PERF_FlagSent, ulCommand, ulArgument, eModuleTo); \
473   } while (0)
474 
475 /** The PERF_RequestingBuffer(s) and PERF_RequestingFrame(s) method
476 *   is used to mark when a buffer (or frame) is beeing requested
477 *   from another module. These go hand-in-hand with
478 *   ReceivedBuffer and ReceivedFrame, if one wants to measure
479 *   the time spent waiting (pending) for a buffer/frame.  Note,
480 *   that the buffer address or size may not be known upon
481 *   calling this method, in which case -1 should be used.
482 *   @param hAPI
483 *       Handle to the PERF object.
484 *   @param ulAddress
485 *       Buffer (or frame) address.
486 *   @param ulSize
487 *       size of buffer(s) that is sent regardless if it is sent
488 *       by pointer exchange or memory copy.
489 *   @param eModuleFrom
490 *       Type of module that is sending the data.
491 * */
492 #define PERF_RequestingBuffer(                                             \
493         hObject,                                                           \
494         ulAddress,                                                         \
495         ulSize,                                                            \
496         eModuleFrom)                                                       \
497   do {                                                                     \
498   __PERF_Location(hObject)                                                 \
499   __PERF_FN(Buffer)(hObject,                                               \
500                     PERF_FlagRequesting, PERF_FlagSingle, PERF_FlagBuffer, \
501                     ulAddress, NULL, ulSize, eModuleFrom, 0);              \
502   } while (0)
503 
504 #define PERF_RequestingFrame(                                             \
505         hObject,                                                          \
506         ulAddress,                                                        \
507         ulSize,                                                           \
508         eModuleFrom)                                                      \
509   do {                                                                    \
510   __PERF_Location(hObject)                                                \
511   __PERF_FN(Buffer)(hObject,                                              \
512                     PERF_FlagRequesting, PERF_FlagSingle, PERF_FlagFrame, \
513                     ulAddress, NULL, ulSize, eModuleFrom, 0);             \
514   } while (0)
515 
516 #define PERF_RequestingBuffers(                                              \
517         hObject,                                                             \
518         ulAddress1,                                                          \
519         ulAddress2,                                                          \
520         ulSize,                                                              \
521         eModuleFrom)                                                         \
522   do {                                                                       \
523   __PERF_Location(hObject)                                                   \
524   __PERF_FN(Buffer)(hObject,                                                 \
525                     PERF_FlagRequesting, PERF_FlagMultiple, PERF_FlagBuffer, \
526                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);         \
527   } while (0)
528 
529 #define PERF_RequestingFrames(                                              \
530         hObject,                                                            \
531         ulAddress1,                                                         \
532         ulAddress2,                                                         \
533         ulSize,                                                             \
534         eModuleFrom)                                                        \
535   do {                                                                      \
536   __PERF_Location(hObject)                                                  \
537   __PERF_FN(Buffer)(hObject,                                                \
538                     PERF_FlagRequesting, PERF_FlagMultiple, PERF_FlagFrame, \
539                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);        \
540   } while (0)
541 
542 /** The PERF_RequestingCommand method is used to mark when a
543 *   command is being requested from another module.  This method
544 *   goes in hand with the PERF_ReceivedCommand to measure the
545 *   time the application is "pending" for the command.  Note,
546 *   that the command is most likely not known when calling this
547 *   method, in which case -1 should be used.
548 *
549 *   @param hObject
550 *       Handle to the PERF object.
551 *   @param ulCommand
552 *       Command.
553 *   @param eModuleTo
554 *       Type of module that sent the data.
555 * */
556 #define PERF_RequestingCommand( \
557         hObject,                \
558         ulCommand,              \
559 		ulArgument,             \
560         eModuleFrom)            \
561   do {                          \
562   __PERF_Location(hObject)      \
563   __PERF_FN(Command)(hObject,   \
564                      PERF_FlagRequesting, ulCommand, ulArgument, eModuleFrom); \
565   } while (0)
566 
567 
568 /** The PERF_ReceivedBuffer(s) and PERF_ReceivedFrame(s) method
569 *   is used to mark when a buffer (or frame) is received from
570 *   another module. These go hand-in-hand with SendingBuffer and
571 *   SendingFrame, if instrumentation is implemented at all
572 *   module boundaries.
573 *   @param hAPI
574 *       Handle to the PERF object.
575 *   @param ulAddress
576 *       Buffer (or frame) address.
577 *   @param ulSize
578 *       size of buffer(s) that is sent regardless if it is sent
579 *       by pointer exchange or memory copy.
580 *   @param eModuleFrom
581 *       Type of module that is sending the data.
582 * */
583 #define PERF_ReceivedBuffer(                                             \
584         hObject,                                                         \
585         ulAddress,                                                       \
586         ulSize,                                                          \
587         eModuleFrom)                                                     \
588   do {                                                                   \
589   __PERF_Location(hObject)                                               \
590   __PERF_FN(Buffer)(hObject,                                             \
591                     PERF_FlagReceived, PERF_FlagSingle, PERF_FlagBuffer, \
592                     ulAddress, NULL, ulSize, eModuleFrom, 0);            \
593   } while (0)
594 
595 #define PERF_ReceivedFrame(                                             \
596         hObject,                                                        \
597         ulAddress,                                                      \
598         ulSize,                                                         \
599         eModuleFrom)                                                    \
600   do {                                                                  \
601   __PERF_Location(hObject)                                              \
602   __PERF_FN(Buffer)(hObject,                                            \
603                     PERF_FlagReceived, PERF_FlagSingle, PERF_FlagFrame, \
604                     ulAddress, NULL, ulSize, eModuleFrom, 0);           \
605   } while (0)
606 
607 #define PERF_ReceivedBuffers(                                              \
608         hObject,                                                           \
609         ulAddress1,                                                        \
610         ulAddress2,                                                        \
611         ulSize,                                                            \
612         eModuleFrom)                                                       \
613   do {                                                                     \
614   __PERF_Location(hObject)                                                 \
615   __PERF_FN(Buffer)(hObject,                                               \
616                     PERF_FlagReceived, PERF_FlagMultiple, PERF_FlagBuffer, \
617                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);       \
618   } while (0)
619 
620 #define PERF_ReceivedFrames(                                              \
621         hObject,                                                          \
622         ulAddress1,                                                       \
623         ulAddress2,                                                       \
624         ulSize,                                                           \
625         eModuleFrom)                                                      \
626   do {                                                                    \
627   __PERF_Location(hObject)                                                \
628   __PERF_FN(Buffer)(hObject,                                              \
629                     PERF_FlagReceived, PERF_FlagMultiple, PERF_FlagFrame, \
630                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);      \
631   } while (0)
632 
633 /** The PERF_ReceivedCommand method is used to mark when a
634 *   command is received from another module.
635 *
636 *   @param hObject
637 *       Handle to the PERF object.
638 *   @param ulCommand
639 *       Command.
640 *   @param eModuleTo
641 *       Type of module that sent the data.
642 * */
643 #define PERF_ReceivedCommand( \
644         hObject,              \
645         ulCommand,            \
646 		ulArgument,           \
647         eModuleFrom)          \
648   do {                        \
649   __PERF_Location(hObject)    \
650   __PERF_FN(Command)(hObject, \
651                      PERF_FlagReceived, ulCommand, ulArgument, eModuleFrom); \
652   } while (0)
653 
654 /** The PERF_XferingBuffer(s) and PERF_XferingFrame(s)
655 *   method is used to mark when a buffer (or frame) is to be
656 *   transferred from one module to another.  This is shortcut
657 *   for PERF_Received followed by PERF_Sending
658 *
659 *   @param hObject
660 *       Handle to the PERF object.
661 *   @param ulAddress or ulAddress1 and ulAddress2
662 *       Buffer (or frame) address(es).
663 *   @param ulSize
664 *       size of buffer(s) that is sent regardless if it is sent
665 *       by pointer exchange or memory copy.
666 *   @param eModuleFrom
667 *       Type of module that is sending the data.
668 *   @param eModuleTo
669 *       Type of module that is receiving the data.
670 * */
671 #define PERF_XferingBuffer(                                             \
672         hObject,                                                        \
673         ulAddress,                                                      \
674         ulSize,                                                         \
675         eModuleFrom,                                                    \
676         eModuleTo)                                                      \
677   do {                                                                  \
678   __PERF_Location(hObject)                                              \
679   __PERF_FN(Buffer)(hObject,                                            \
680                     PERF_FlagXfering, PERF_FlagSingle, PERF_FlagBuffer, \
681                     ulAddress, NULL, ulSize, eModuleFrom, eModuleTo);   \
682   } while (0)
683 
684 #define PERF_XferingFrame(                                             \
685         hObject,                                                       \
686         ulAddress,                                                     \
687         ulSize,                                                        \
688         eModuleFrom,                                                   \
689         eModuleTo)                                                     \
690   do {                                                                 \
691   __PERF_Location(hObject)                                             \
692   __PERF_FN(Buffer)(hObject,                                           \
693                     PERF_FlagXfering, PERF_FlagSingle, PERF_FlagFrame, \
694                     ulAddress, NULL, ulSize, eModuleFrom, eModuleTo);  \
695   } while (0)
696 
697 #define PERF_XferingBuffers(                                              \
698         hObject,                                                          \
699         ulAddress1,                                                       \
700         ulAddress2,                                                       \
701         ulSize,                                                           \
702         eModuleFrom,                                                      \
703         eModuleTo)                                                        \
704   do {                                                                    \
705   __PERF_Location(hObject)                                                \
706   __PERF_FN(Buffer)(hObject,                                              \
707                     PERF_FlagXfering, PERF_FlagMultiple, PERF_FlagBuffer, \
708                     ulAddress1, ulAddress2, ulSize, eModuleFrom, eModuleTo);\
709   } while (0)
710 
711 #define PERF_XferingFrames(                                              \
712         hObject,                                                         \
713         ulAddress1,                                                      \
714         ulAddress2,                                                      \
715         ulSize,                                                          \
716         eModuleFrom,                                                     \
717         eModuleTo)                                                       \
718   do {                                                                   \
719   __PERF_Location(hObject)                                               \
720   __PERF_FN(Buffer)(hObject,                                             \
721                     PERF_FlagXfering, PERF_FlagMultiple, PERF_FlagFrame, \
722                     ulAddress1, ulAddress2, ulSize, eModuleFrom, eModuleTo);\
723   } while (0)
724 
725 /** The PERF_SyncData method shall be called by a module that
726 *   synchronizes audio/video streams.  It informs the
727 *   instrumentation module about the tempTime stamps of the two
728 *   streams, as well as the operation (if any) to restore
729 *   synchronization.
730 *   @param hObject
731 *       Handle to the PERF object.
732 *   @param pfTimeAudio
733 *       Time stamp of audio frame
734 *   @param pfTimeVideo
735 *       Time stamp of video frame
736 *   @param eSyncOperation
737 *       Synchronization operation that is being taken to get
738 *       streams in sync.
739 * */
740 #define PERF_SyncAV(       \
741         hObject,           \
742         fTimeAudio,        \
743         fTimeVideo,        \
744         eSyncOperation)    \
745   do {                     \
746   __PERF_Location(hObject) \
747     __PERF_FN(SyncAV)(hObject, fTimeAudio, fTimeVideo, eSyncOperation); \
748   } while (0)
749 
750 /** The PERF_TheadCreated method shall be called after creating
751 *   a new thread.
752 *   @param hObject
753 *       Handle to the PERF object.
754 *   @param pfTimeAudio
755 *       Time stamp of audio frame
756 *   @param pfTimeVideo
757 *       Time stamp of video frame
758 *   @param eSyncOperation
759 *       Synchronization operation that is being taken to get
760 *       streams in sync.
761 * */
762 #define PERF_ThreadCreated( \
763         hObject,            \
764         ulThreadID,         \
765         ulThreadName)       \
766   do {                      \
767   __PERF_Location(hObject)  \
768     __PERF_FN(ThreadCreated)(hObject, ulThreadID, ulThreadName); \
769   }  while (0)
770 
771 /** The PERF_Log method can be called to log 3 values into the
772 *   log.  The 1st argument is capped at 28 bits.
773 *   @param hObject
774 *       Handle to the PERF object.
775 *   @param ulData1, ulData2, ulData3
776 *       Data to be logged
777 * */
778 #define PERF_Log( \
779         hObject,  \
780         ulData1,  \
781         ulData2,  \
782         ulData3)  \
783   do {            \
784   __PERF_Location(hObject) \
785     __PERF_FN(Log)(hObject, ulData1, ulData2, ulData3);\
786   } while (0)
787 
788 /* define PERF_OBJ and the used __PERF macros */
789 #include "perf_obj.h"
790 
791 #endif /* __PERF_INSTURMENTATION__ */
792 
793 #endif /* __PERF_H__ */
794 
795 
796