1fe31b3c311c4aae505e0dae18f3f828190a51c4
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / qsv / libmfx / dispatcher / windows / mfx_dispatcher_log.h
1 /*############################################################################
2   # Copyright (C) 2012-2020 Intel Corporation
3   #
4   # SPDX-License-Identifier: MIT
5   ############################################################################*/
6
7 #ifndef DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
8 #define DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
9
10 //////////////////////////////////////////////////////////////////////////
11 //dispatcher log (DL) level
12 #define DL_INFO           1
13 #define DL_WRN            2
14 #define DL_ERROR          4
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
23
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))
29
30 #define MFXGUIDTYPE() "%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X"
31
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], \
36         (guid)->Data[15]
37
38 #if defined(MFX_DISPATCHER_LOG)
39
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
45
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
50
51     // guid for all dispatcher events
52     #define DISPATCHER_LOG_EVENT_GUID L"{EB0538CC-4FEE-484d-ACEE-1182E9F37A57}"
53
54     //puts a sink into listeners list
55     //#define DISPATCHER_LOG_REGISTER_EVENT_PROVIDER
56
57     //puts a sink into listeners list
58     //#define DISPATCHER_LOG_REGISTER_FILE_WRITER
59     #define DISPACTHER_LOG_FW_PATH "c:\\dispatcher.log"
60
61     #include <stdarg.h>
62     #include <stdio.h>
63
64 //callback interface for intercept logging messages
65 class IMsgHandler {
66 public:
67     virtual ~IMsgHandler() {}
68     virtual void Write(int level, int opcode, const char *msg, va_list argptr) = 0;
69 };
70
71     #if DISPATCHER_LOG_USE_FORMATING
72
73         #define DISPATCHER_LOG(lvl, opcode, str)              \
74             {                                                 \
75                 DispatcherLogBracketsHelper wrt(lvl, opcode); \
76                 wrt.Write str;                                \
77             }
78     #else
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)              \
83             {                                                 \
84                 DispatcherLogBracketsHelper wrt(lvl, opcode); \
85                 DISPATCHER_LOG_VA_ARGS str;                   \
86             }
87     #endif //DISPATCHER_LOG_USE_FORMATING
88
89     #define DISPATCHER_LOG_OPERATION(operation) operation
90
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__)
94
95     #define DISPATCHER_LOG_AUTO(lvl, msg)                        \
96         DispatchLogBlockHelper name_from_line(__auto_log_)(lvl); \
97         name_from_line(__auto_log_).Write msg;
98
99     #include <list>
100     #include <map>
101     #include <memory>
102     #include <string>
103
104 template <class T>
105 class DSSingleTone {
106 public:
107     template <class TParam1>
108     inline static T &get(TParam1 par1) {
109         T *pstored;
110         if (NULL == (pstored = store_or_load())) {
111             return *store_or_load(new T(par1));
112         }
113         return *pstored;
114     }
115
116     inline static T &get() {
117         T *pstored;
118         if (NULL == (pstored = store_or_load())) {
119             return *store_or_load(new T());
120         }
121         return *pstored;
122     }
123
124 private:
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;
129         if (NULL != obj) {
130             instance.reset(obj);
131         }
132         return instance.get();
133     }
134 };
135
136 class DispatchLog : public DSSingleTone<DispatchLog> {
137     friend class DSSingleTone<DispatchLog>;
138     std::list<IMsgHandler *> m_Recepients;
139     int m_DispatcherLogSink;
140
141 public:
142     //sets current sink
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);
149
150 protected:
151     DispatchLog();
152 };
153
154 //allows to push arguments on the stack without declaring them as function parameters
155 struct DispatcherLogBracketsHelper {
156     int m_level;
157     int m_opcode;
158     DispatcherLogBracketsHelper(int level, int opcode) : m_level(level), m_opcode(opcode) {}
159     void Write(const char *str, ...);
160 };
161
162 //auto log on ctor dtor
163 struct DispatchLogBlockHelper {
164     int m_level;
165     void Write(const char *str, ...);
166     explicit DispatchLogBlockHelper(int level) : m_level(level) {}
167     ~DispatchLogBlockHelper();
168 };
169
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;
176
177 public:
178     ~ETWHandlerFactory();
179     IMsgHandler *GetSink(const wchar_t *sguid = DISPATCHER_LOG_EVENT_GUID);
180
181 protected:
182     ETWHandlerFactory() {}
183 };
184     #endif
185
186     #if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER)
187 class FileSink : public DSSingleTone<FileSink>, public IMsgHandler {
188     friend class DSSingleTone<FileSink>;
189
190 public:
191     virtual void Write(int level, int opcode, const char *msg, va_list argptr);
192     FileSink() : m_hdl(NULL) {}
193     ~FileSink() {
194         if (NULL != m_hdl)
195             fclose(m_hdl);
196     }
197
198 private:
199     FILE *m_hdl;
200     explicit FileSink(const std::string &log_file) {
201         fopen_s(&m_hdl, log_file.c_str(), "a");
202     }
203 };
204     #endif
205
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);
210
211 #else // !defined(MFX_DISPATCHER_LOG)
212
213     #define DISPATCHER_LOG(level, opcode, message)
214     #define DISPATCHER_LOG_AUTO(level, message)
215     #define DISPATCHER_LOG_OPERATION(operation)
216
217 #endif // !defined(MFX_DISPATCHER_LOG)
218
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)
224
225 #endif // DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_