1 /*############################################################################
2 # Copyright (C) 2012-2020 Intel Corporation
4 # SPDX-License-Identifier: MIT
5 ############################################################################*/
7 #ifndef DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
8 #define DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
10 //////////////////////////////////////////////////////////////////////////
11 //dispatcher log (DL) level
15 #define DL_LOADED_LIBRARY 8
16 //////////////////////////////////////////////////////////////////////////
17 //opcodes used only in events
18 enum { DL_EVENT_START = 1, DL_EVENT_STOP, DL_EVENT_MSG };
19 //////////////////////////////////////////////////////////////////////////
20 #define DL_SINK_NULL 0
21 #define DL_SINK_PRINTF 1
22 #define DL_SINK_IMsgHandler 2
24 #define MFXFOURCCTYPE() "%c%c%c%c"
25 #define ZERO_OR_SPACE(value) ((0 == (value)) ? '0' : (value))
26 #define MFXU32TOFOURCC(mfxu32) \
27 ZERO_OR_SPACE((char)(mfxu32 & 0xFF)), ZERO_OR_SPACE((char)((mfxu32 >> 8) & 0xFF)), \
28 ZERO_OR_SPACE((char)((mfxu32 >> 16) & 0xFF)), ZERO_OR_SPACE((char)((mfxu32 >> 24) & 0xFF))
30 #define MFXGUIDTYPE() "%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X"
32 #define MFXGUIDTOHEX(guid) \
33 (guid)->Data[0], (guid)->Data[1], (guid)->Data[2], (guid)->Data[3], (guid)->Data[4], \
34 (guid)->Data[5], (guid)->Data[6], (guid)->Data[7], (guid)->Data[8], (guid)->Data[9], \
35 (guid)->Data[10], (guid)->Data[11], (guid)->Data[12], (guid)->Data[13], (guid)->Data[14], \
38 #if defined(MFX_DISPATCHER_LOG)
40 //---------------------------setup section------------------------
41 //using of formating instead of variadic macro with NULL end,
42 //leads to more flexibility in format, however constructing string
43 //with vsprintf_s is a time wasting
44 #define DISPATCHER_LOG_USE_FORMATING 1
46 //creates unique object, event guid registration, factories on heap
47 //heap reduce stack allocation and reduce reservation time at startup
48 //is a vital if mediasdk wont use
49 #define DISPATCHER_LOG_HEAP_SINGLETONES
51 // guid for all dispatcher events
52 #define DISPATCHER_LOG_EVENT_GUID L"{EB0538CC-4FEE-484d-ACEE-1182E9F37A57}"
54 //puts a sink into listeners list
55 //#define DISPATCHER_LOG_REGISTER_EVENT_PROVIDER
57 //puts a sink into listeners list
58 //#define DISPATCHER_LOG_REGISTER_FILE_WRITER
59 #define DISPACTHER_LOG_FW_PATH "c:\\dispatcher.log"
64 //callback interface for intercept logging messages
67 virtual ~IMsgHandler() {}
68 virtual void Write(int level, int opcode, const char *msg, va_list argptr) = 0;
71 #if DISPATCHER_LOG_USE_FORMATING
73 #define DISPATCHER_LOG(lvl, opcode, str) \
75 DispatcherLogBracketsHelper wrt(lvl, opcode); \
79 #define DISPATCHER_LOG_VA_ARGS(...) wrt.Write(__VA_ARGS__, NULL)
80 //WARNING: don't use types that occupy more that 4 bytes in memory
81 //WARNING: don't use %s in format specifier
82 #define DISPATCHER_LOG(lvl, opcode, str) \
84 DispatcherLogBracketsHelper wrt(lvl, opcode); \
85 DISPATCHER_LOG_VA_ARGS str; \
87 #endif //DISPATCHER_LOG_USE_FORMATING
89 #define DISPATCHER_LOG_OPERATION(operation) operation
91 #define __name_from_line(name, line) name##line
92 #define _name_from_line(name, line) __name_from_line(name, line)
93 #define name_from_line(name) _name_from_line(name, __LINE__)
95 #define DISPATCHER_LOG_AUTO(lvl, msg) \
96 DispatchLogBlockHelper name_from_line(__auto_log_)(lvl); \
97 name_from_line(__auto_log_).Write msg;
107 template <class TParam1>
108 inline static T &get(TParam1 par1) {
110 if (NULL == (pstored = store_or_load())) {
111 return *store_or_load(new T(par1));
116 inline static T &get() {
118 if (NULL == (pstored = store_or_load())) {
119 return *store_or_load(new T());
125 //if obj == NULL, then it load
126 //if obj != NULL then it store obj
127 inline static T *store_or_load(T *obj = NULL) {
128 static std::unique_ptr<T> instance;
132 return instance.get();
136 class DispatchLog : public DSSingleTone<DispatchLog> {
137 friend class DSSingleTone<DispatchLog>;
138 std::list<IMsgHandler *> m_Recepients;
139 int m_DispatcherLogSink;
143 void SetSink(int nsink, IMsgHandler *pHandler);
144 void AttachSink(int nsink, IMsgHandler *pHandler);
145 void DetachSink(int nsink, IMsgHandler *pHandler);
146 void ExchangeSink(int nsink, IMsgHandler *pOld, IMsgHandler *pNew);
147 void DetachAllSinks();
148 void Write(int level, int opcode, const char *msg, va_list argptr);
154 //allows to push arguments on the stack without declaring them as function parameters
155 struct DispatcherLogBracketsHelper {
158 DispatcherLogBracketsHelper(int level, int opcode) : m_level(level), m_opcode(opcode) {}
159 void Write(const char *str, ...);
162 //auto log on ctor dtor
163 struct DispatchLogBlockHelper {
165 void Write(const char *str, ...);
166 explicit DispatchLogBlockHelper(int level) : m_level(level) {}
167 ~DispatchLogBlockHelper();
170 //----utility sinks-----
171 #if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
172 class ETWHandlerFactory : public DSSingleTone<ETWHandlerFactory> {
173 friend class DSSingleTone<ETWHandlerFactory>;
174 typedef std::map<std::wstring, IMsgHandler *> _storage_type;
175 _storage_type m_storage;
178 ~ETWHandlerFactory();
179 IMsgHandler *GetSink(const wchar_t *sguid = DISPATCHER_LOG_EVENT_GUID);
182 ETWHandlerFactory() {}
186 #if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER)
187 class FileSink : public DSSingleTone<FileSink>, public IMsgHandler {
188 friend class DSSingleTone<FileSink>;
191 virtual void Write(int level, int opcode, const char *msg, va_list argptr);
192 FileSink() : m_hdl(NULL) {}
200 explicit FileSink(const std::string &log_file) {
201 fopen_s(&m_hdl, log_file.c_str(), "a");
206 //-----utility functions
207 //since they are not called outside of macro we can define them here
208 std::string DispatcherLog_GetMFXImplString(int impl);
209 const char *DispatcherLog_GetMFXStatusString(int sts);
211 #else // !defined(MFX_DISPATCHER_LOG)
213 #define DISPATCHER_LOG(level, opcode, message)
214 #define DISPATCHER_LOG_AUTO(level, message)
215 #define DISPATCHER_LOG_OPERATION(operation)
217 #endif // !defined(MFX_DISPATCHER_LOG)
219 #define DISPATCHER_LOG_INFO(msg) DISPATCHER_LOG(DL_INFO, DL_EVENT_MSG, msg)
220 #define DISPATCHER_LOG_WRN(msg) DISPATCHER_LOG(DL_WRN, DL_EVENT_MSG, msg)
221 #define DISPATCHER_LOG_ERROR(msg) DISPATCHER_LOG(DL_ERROR, DL_EVENT_MSG, msg)
222 #define DISPATCHER_LOG_LIBRARY(msg) DISPATCHER_LOG(DL_LOADED_LIBRARY, DL_EVENT_MSG, msg)
223 #define DISPATCHER_LOG_BLOCK(msg) DISPATCHER_LOG_AUTO(DL_INFO, msg)
225 #endif // DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_