• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "gst_loader.h"
17 #include <string>
18 #include <map>
19 #include <queue>
20 #include <glib.h>
21 #include <gst/gst.h>
22 #include "string_ex.h"
23 #include "param_wrapper.h"
24 #include "media_errors.h"
25 #include "media_log.h"
26 
27 namespace {
28     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "GstLoader"};
29     const std::map<char, GstDebugLevel> LOG_LEVEL_TO_GST_LEVEL = {
30         {'E', GST_LEVEL_ERROR},
31         {'W', GST_LEVEL_WARNING},
32         {'I', GST_LEVEL_INFO},
33         {'D', GST_LEVEL_DEBUG},
34         {'L', GST_LEVEL_LOG},
35         {'T', GST_LEVEL_TRACE},
36     };
37     const std::string g_gstDftTag = "*";
38     const std::vector<const gchar *> GST_ARGS = {
39         "ohos_media_service",
40         "--gst-disable-registry-fork",
41 #ifdef __aarch64__
42         "--gst-plugin-path=/system/lib64/media/plugins"
43 #else
44         "--gst-plugin-path=/system/lib/media/plugins"
45 #endif
46     };
47 }
48 
49 namespace OHOS {
50 namespace Media {
51 struct GstLogPrintInfo {
52     GstDebugLevel level;
53     const gchar *file;
54     const gchar *function;
55     gint line;
56     GObject *object;
57     const char *logMsg;
58     const char *modeName;
59 };
60 
GstLogPrint(const GstLogPrintInfo & info)61 static void GstLogPrint(const GstLogPrintInfo &info)
62 {
63     const gchar *objName = GST_IS_OBJECT(info.object) ? GST_OBJECT_NAME(info.object) : " ";
64     objName = objName ? objName : " ";
65     OHOS::HiviewDFX::HiLogLabel gstLable = {LOG_CORE, LOG_DOMAIN, info.modeName};
66 
67     switch (info.level) {
68         case GST_LEVEL_TRACE: // no break
69         case GST_LEVEL_LOG:   // no break
70         case GST_LEVEL_DEBUG:
71             (void)::OHOS::HiviewDFX::HiLog::Debug(gstLable,
72                 "{%{public}s():%{public}d} [gst::%{public}s:%{public}" PRIXPTR "] %{public}s",
73                 info.function, info.line, objName, FAKE_POINTER(info.object), info.logMsg);
74             break;
75         case GST_LEVEL_INFO:
76             (void)::OHOS::HiviewDFX::HiLog::Info(gstLable,
77                 "{%{public}s():%{public}d} [gst::%{public}s:%{public}" PRIXPTR "] %{public}s",
78                 info.function, info.line, objName, FAKE_POINTER(info.object), info.logMsg);
79             break;
80         case GST_LEVEL_WARNING:
81             (void)::OHOS::HiviewDFX::HiLog::Warn(gstLable,
82                 "{%{public}s():%{public}d} [gst::%{public}s:%{public}" PRIXPTR "] %{public}s",
83                 info.function, info.line, objName, FAKE_POINTER(info.object), info.logMsg);
84             break;
85         case GST_LEVEL_ERROR:
86             (void)::OHOS::HiviewDFX::HiLog::Error(gstLable,
87                 "{%{public}s():%{public}d} [gst::%{public}s:%{public}" PRIXPTR "] %{public}s",
88                 info.function, info.line, objName, FAKE_POINTER(info.object), info.logMsg);
89             break;
90         default:
91             break;
92     }
93 }
94 
GstLogCallbackFunc(GstDebugCategory * category,GstDebugLevel level,const gchar * file,const gchar * function,gint line,GObject * object,GstDebugMessage * message,gpointer userData)95 static void GstLogCallbackFunc(GstDebugCategory *category, GstDebugLevel level, const gchar *file,
96     const gchar *function, gint line, GObject *object, GstDebugMessage *message, gpointer userData)
97 {
98     const gchar *modeName = nullptr;
99     (void)userData;
100 
101     if (message == nullptr) {
102         return;
103     }
104     if (category != nullptr) {
105         if (level > gst_debug_category_get_threshold(category)) {
106             return;
107         }
108         modeName = gst_debug_category_get_name(category);
109     } else {
110         if (level > gst_debug_get_default_threshold()) {
111             return;
112         }
113     }
114 
115     if (modeName == nullptr) {
116         modeName = LABEL.tag;
117     }
118 
119     const gchar *logMsg = gst_debug_message_get(message);
120     if (logMsg == nullptr) {
121         return;
122     }
123     GstLogPrintInfo printInfo = {level, file ? file : " ", function ? function : " ", line, object, logMsg, modeName};
124     GstLogPrint(printInfo);
125 }
126 
GLogCallbackFunc(const gchar * logDomain,GLogLevelFlags level,const gchar * message,gpointer userData)127 static void GLogCallbackFunc(const gchar *logDomain, GLogLevelFlags level, const gchar *message, gpointer userData)
128 {
129     const gchar *modeName = logDomain;
130     (void)userData;
131 
132     if (message == nullptr || level > G_LOG_LEVEL_WARNING) {
133         return;
134     }
135 
136     if (modeName == nullptr) {
137         modeName = LABEL.tag;
138     }
139     OHOS::HiviewDFX::HiLogLabel glibLable = {LOG_CORE, LOG_DOMAIN, modeName};
140 
141     switch (level) {
142         case G_LOG_LEVEL_WARNING:
143             (void)::OHOS::HiviewDFX::HiLog::Warn(glibLable, "[glog] %{public}s", message);
144             break;
145         case G_LOG_LEVEL_CRITICAL: // no break
146         case G_LOG_LEVEL_ERROR:    // no break
147         case G_LOG_FLAG_RECURSION:
148             (void)::OHOS::HiviewDFX::HiLog::Error(glibLable, "[glog] %{public}s", message);
149             break;
150         default:
151             break;
152     }
153 }
154 
EnableGLog(GLogFunc func)155 static void EnableGLog(GLogFunc func)
156 {
157     // map glib default log handler, and gstreamer log hander to GLogMap
158     (void)g_log_set_default_handler(func, nullptr);
159     (void)g_log_set_handler("GStreamer", static_cast<GLogLevelFlags>(0xFFFFFFFF), func, nullptr);
160 
161     return;
162 }
163 
SetGstLogLevelFromSysPara()164 static void SetGstLogLevelFromSysPara()
165 {
166     std::string levelPara;
167     int res = OHOS::system::GetStringParameter("sys.media.log.level", levelPara, "");
168     if (res != 0 || levelPara.empty()) {
169         gst_debug_set_default_threshold (GST_LEVEL_WARNING);
170         MEDIA_LOGD("sys.media.log.level not find");
171         return;
172     }
173     MEDIA_LOGD("sys.media.log.level=%{public}s", levelPara.c_str());
174 
175     static std::map<std::string, char> logTagLevelMap = { { g_gstDftTag, 'I' } };
176     std::vector<std::string> tagLevelVec;
177     SplitStr(levelPara, ",", tagLevelVec, false, true);
178     for (auto &tagLevel : tagLevelVec) {
179         std::vector<std::string> item;
180         SplitStr(tagLevel, ":", item, false, true); // module format:"tagname:level"
181         if (item.size() < 2) { // module format:"tagname:level"
182             continue;
183         }
184         std::string &tag = item[0];
185         if (tag.size() >= 128) { // max tag size is 128
186             continue;
187         }
188         if (logTagLevelMap.size() >= 512 && logTagLevelMap.count(tag) == 0) { // 512 is max tag number
189             continue;
190         }
191         std::string &level = item[1];
192         if (level.empty() || LOG_LEVEL_TO_GST_LEVEL.count(level.c_str()[0]) == 0) {
193             continue;
194         }
195 
196         logTagLevelMap[tag] = level.c_str()[0];
197         MEDIA_LOGI("logPrara:%{public}s:%{public}c", tag.c_str(), level.c_str()[0]);
198     }
199     gst_debug_set_default_threshold(LOG_LEVEL_TO_GST_LEVEL.at(logTagLevelMap[g_gstDftTag]));
200     for (auto &&[tag, levelCode] : logTagLevelMap) {
201         if (tag == g_gstDftTag) {
202             continue;
203         }
204         GstDebugCategory *cat = _gst_debug_get_category(tag.c_str());
205         if (cat == nullptr) {
206             continue;
207         }
208         gst_debug_category_set_threshold(cat, LOG_LEVEL_TO_GST_LEVEL.at(logTagLevelMap[tag]));
209     }
210 }
211 
CreateGstInitArgv()212 static gchar ***CreateGstInitArgv()
213 {
214     gchar ***argv = nullptr;
215     argv = static_cast<gchar ***>(new (std::nothrow) (gchar **));
216     if (argv == nullptr) {
217         MEDIA_LOGI("new argv failed");
218         return nullptr;
219     }
220     *argv = static_cast<gchar **>(new (std::nothrow) gchar *[GST_ARGS.size()]);
221     if (*argv == nullptr) {
222         delete argv;
223         return nullptr;
224     }
225     for (size_t i = 0; i < GST_ARGS.size(); i++) {
226         (*argv)[i] = const_cast<gchar *>(GST_ARGS[i]);
227     }
228 
229     return argv;
230 }
231 
DestroyGstInitArgv(gchar *** argv)232 static void DestroyGstInitArgv(gchar ***argv)
233 {
234     if (argv == nullptr) {
235         return;
236     }
237     if (*argv == nullptr) {
238         delete argv;
239         return;
240     }
241     delete [] *argv;
242     delete argv;
243 }
244 
SetUp()245 int32_t GstLoader::SetUp()
246 {
247     std::lock_guard<std::mutex> lock(mutex_);
248     if (isInit_) {
249         return MSERR_OK;
250     }
251 
252     EnableGLog(GLogCallbackFunc);
253     gst_debug_remove_log_function(gst_debug_log_default);
254     gst_debug_add_log_function(GstLogCallbackFunc, nullptr, nullptr);
255     SetGstLogLevelFromSysPara();
256     int32_t argc = static_cast<int32_t>(GST_ARGS.size());
257     MEDIA_LOGI("SetUp GstLoader argc=%{public}d", argc);
258     gchar ***argv = CreateGstInitArgv();
259     if (argv == nullptr) {
260         return MSERR_NO_MEMORY;
261     }
262     gst_init(&argc, argv);
263     DestroyGstInitArgv(argv);
264     isInit_ = true;
265 
266     MEDIA_LOGI("SetUp GstLoader finished!");
267 
268     return MSERR_OK;
269 }
270 
UpdateLogLevel() const271 void GstLoader::UpdateLogLevel() const
272 {
273     SetGstLogLevelFromSysPara();
274 }
275 }
276 }
277