1 //------------------------------------------------------------------------------
4 // Desc: DirectShow base classes.
6 // Copyright (c) Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
11 The idea is to pepper the source code with interesting measurements and
12 have the last few thousand of these recorded in a circular buffer that
13 can be post-processed to give interesting numbers.
15 WHAT THE LOG LOOKS LIKE:
17 Time (sec) Type Delta Incident_Name
18 0.055,41 NOTE -. Incident Nine - Another note
19 0.055,42 NOTE 0.000,01 Incident Nine - Another note
20 0.055,44 NOTE 0.000,02 Incident Nine - Another note
21 0.055,45 STOP -. Incident Eight - Also random
22 0.055,47 START -. Incident Seven - Random
23 0.055,49 NOTE 0.000,05 Incident Nine - Another note
24 ------- <etc. there is a lot of this> ----------------
25 0.125,60 STOP 0.000,03 Msr_Stop
26 0.125,62 START -. Msr_Start
27 0.125,63 START -. Incident Two - Start/Stop
28 0.125,65 STOP 0.000,03 Msr_Start
29 0.125,66 START -. Msr_Stop
30 0.125,68 STOP 0.000,05 Incident Two - Start/Stop
31 0.125,70 STOP 0.000,04 Msr_Stop
32 0.125,72 START -. Msr_Start
33 0.125,73 START -. Incident Two - Start/Stop
34 0.125,75 STOP 0.000,03 Msr_Start
35 0.125,77 START -. Msr_Stop
36 0.125,78 STOP 0.000,05 Incident Two - Start/Stop
37 0.125,80 STOP 0.000,03 Msr_Stop
38 0.125,81 NOTE -. Incident Three - single Note
39 0.125,83 START -. Incident Four - Start, no stop
40 0.125,85 START -. Incident Five - Single Start/Stop
41 0.125,87 STOP 0.000,02 Incident Five - Single Start/Stop
43 Number Average StdDev Smallest Largest Incident_Name
44 10 0.000,58 0.000,10 0.000,55 0.000,85 Incident One - Note
45 50 0.000,05 0.000,00 0.000,05 0.000,05 Incident Two - Start/Stop
46 1 -. -. -. -. Incident Three - single Note
47 0 -. -. -. -. Incident Four - Start, no stop
48 1 0.000,02 -. 0.000,02 0.000,02 Incident Five - Single Start/Stop
49 0 -. -. -. -. Incident Six - zero occurrences
50 100 0.000,25 0.000,12 0.000,02 0.000,62 Incident Seven - Random
51 100 0.000,79 0.000,48 0.000,02 0.001,92 Incident Eight - Also random
52 5895 0.000,01 0.000,01 0.000,01 0.000,56 Incident Nine - Another note
53 10 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Note
54 50 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Start
55 50 0.000,04 0.000,03 0.000,03 0.000,31 Msr_Stop
58 The log shows what happened and when. Each line shows the time at which
59 something happened (see WHAT YOU CODE below) what it was that happened
60 and (if approporate) the time since the corresponding previous event
61 (that's the delta column).
63 The statistics show how many times each event occurred, what the average
64 delta time was, also the standard deviation, largest and smalles delta.
68 Before anything else executes: - register your ids
70 int id1 = Msr_Register("Incident One - Note");
71 int id2 = Msr_Register("Incident Two - Start/Stop");
72 int id3 = Msr_Register("Incident Three - single Note");
75 At interesting moments:
77 // To measure a repetitive event - e.g. end of bitblt to screen
78 Msr_Note(Id9); // e.g. "video frame hiting the screen NOW!"
82 // To measure an elapsed time e.g. time taken to decode an MPEG B-frame
83 Msr_Start(Id2); // e.g. "Starting to decode MPEG B-frame"
85 MsrStop(Id2); // "Finished MPEG decode"
90 hFile = CreateFile("Perf.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
91 Msr_Dump(hFile); // This writes the log out to the file
96 Msr_Dump(NULL); // This writes it to DbgLog((LOG_TRACE,0, ... ));
97 // but if you are writing it out to the debugger
98 // then the times are probably all garbage because
99 // the debugger can make things run awfully slow.
101 A given id should be used either for start / stop or Note calls. If Notes
102 are mixed in with Starts and Stops their statistics will be gibberish.
104 If you code the calls in upper case i.e. MSR_START(idMunge); then you get
105 macros which will turn into nothing unless PERF is defined.
107 You can reset the statistical counts for a given id by calling Reset(Id).
108 They are reset by default at the start.
109 It logs Reset as a special incident, so you can see it in the log.
111 The log is a circular buffer in storage (to try to minimise disk I/O).
112 It overwrites the oldest entries once full. The statistics include ALL
113 incidents since the last Reset, whether still visible in the log or not.
120 #define MSR_INIT() Msr_Init()
121 #define MSR_TERMINATE() Msr_Terminate()
122 #define MSR_REGISTER(a) Msr_Register(a)
123 #define MSR_RESET(a) Msr_Reset(a)
124 #define MSR_CONTROL(a) Msr_Control(a)
125 #define MSR_START(a) Msr_Start(a)
126 #define MSR_STOP(a) Msr_Stop(a)
127 #define MSR_NOTE(a) Msr_Note(a)
128 #define MSR_INTEGER(a,b) Msr_Integer(a,b)
129 #define MSR_DUMP(a) Msr_Dump(a)
130 #define MSR_DUMPSTATS(a) Msr_DumpStats(a)
132 #define MSR_INIT() ((void)0)
133 #define MSR_TERMINATE() ((void)0)
134 #define MSR_REGISTER(a) 0
135 #define MSR_RESET(a) ((void)0)
136 #define MSR_CONTROL(a) ((void)0)
137 #define MSR_START(a) ((void)0)
138 #define MSR_STOP(a) ((void)0)
139 #define MSR_NOTE(a) ((void)0)
140 #define MSR_INTEGER(a,b) ((void)0)
141 #define MSR_DUMP(a) ((void)0)
142 #define MSR_DUMPSTATS(a) ((void)0)
149 // This must be called first - (called by the DllEntry)
151 void WINAPI
Msr_Init(void);
154 // Call this last to clean up (or just let it fall off the end - who cares?)
156 void WINAPI
Msr_Terminate(void);
159 // Call this to get an Id for an "incident" that you can pass to Start, Stop or Note
160 // everything that's logged is called an "incident".
162 int WINAPI
Msr_Register(LPTSTR Incident
);
165 // Reset the statistical counts for an incident
167 void WINAPI
Msr_Reset(int Id
);
170 // Reset all the counts for all incidents
171 #define MSR_RESET_ALL 0
175 void WINAPI
Msr_Control(int iAction
);
178 // log the start of an operation
180 void WINAPI
Msr_Start(int Id
);
183 // log the end of an operation
185 void WINAPI
Msr_Stop(int Id
);
188 // log a one-off or repetitive operation
190 void WINAPI
Msr_Note(int Id
);
193 // log an integer (on which we can see statistics later)
194 void WINAPI
Msr_Integer(int Id
, int n
);
197 // print out all the vaialable log (it may have wrapped) and then the statistics.
198 // When the log wraps you lose log but the statistics are still complete.
199 // hFIle==NULL => use DbgLog
200 // otherwise hFile must have come from CreateFile or OpenFile.
202 void WINAPI
Msr_Dump(HANDLE hFile
);
205 // just dump the statistics - never mind the log
207 void WINAPI
Msr_DumpStats(HANDLE hFile
);
209 // Type definitions in case you want to declare a pointer to the dump functions
210 // (makes it a trifle easier to do dynamic linking
211 // i.e. LoadModule, GetProcAddress and call that)
213 // Typedefs so can declare MSR_DUMPPROC *MsrDumpStats; or whatever
214 typedef void WINAPI
MSR_DUMPPROC(HANDLE hFile
);
215 typedef void WINAPI
MSR_CONTROLPROC(int iAction
);
222 #endif // __MEASURE__