• 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 #ifndef COMMON_NAPI_H
17 #define COMMON_NAPI_H
18 
19 #include <string>
20 #include <vector>
21 #include <unordered_map>
22 #include "meta/format.h"
23 #include "av_common.h"
24 #include "napi/native_api.h"
25 #include "napi/native_node_api.h"
26 #include "media_core.h"
27 #include "audio_info.h"
28 #include "audio_system_manager.h"
29 
30 namespace OHOS {
31 namespace Media {
32 struct AVFileDescriptor;
33 
34 class CommonNapi {
35 public:
36     CommonNapi() = delete;
37     ~CommonNapi() = delete;
38     static std::string GetStringArgument(napi_env env, napi_value value);
39     static bool CheckValueType(napi_env env, napi_value arg, napi_valuetype type);
40     static bool GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result);
41     static bool GetPropertyUint32(napi_env env, napi_value configObj, const std::string &type, uint32_t &result);
42     static bool GetPropertyInt64(napi_env env, napi_value configObj, const std::string &type, int64_t &result);
43     static bool GetPropertyDouble(napi_env env, napi_value configObj, const std::string &type, double &result);
44     static std::string GetPropertyString(napi_env env, napi_value configObj, const std::string &type);
45     static bool GetFdArgument(napi_env env, napi_value value, AVFileDescriptor &rawFd);
46     static napi_status FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args);
47     static napi_status CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal);
48     static napi_ref CreateReference(napi_env env, napi_value arg);
49     static napi_deferred CreatePromise(napi_env env, napi_ref ref, napi_value &result);
50     static bool SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value);
51     static bool SetPropertyDouble(napi_env env, napi_value &obj, const std::string &key, double value);
52     static bool SetPropertyBool(napi_env env, napi_value &obj, const std::string &key, bool value);
53     static bool SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value);
54     static napi_value CreateFormatBuffer(napi_env env, Format &format);
55     static bool CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result);
56     static bool AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max);
57     static bool AddArrayProperty(napi_env env, napi_value obj, const std::string &name,
58         const std::vector<int32_t> &vec);
59     static bool AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value);
60     static bool AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value);
61     static bool AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec);
62     static bool AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value);
63     static bool GetPropertyBool(napi_env env, napi_value configObj, const std::string &type, bool &result);
64 
65     static void ConvertDeviceInfoToAudioDeviceDescriptor(
66         sptr<AudioStandard::AudioDeviceDescriptor> audioDeviceDescriptor, const AudioStandard::DeviceInfo &deviceInfo);
67     static napi_status SetValueDeviceInfo(const napi_env &env, const AudioStandard::DeviceInfo &deviceInfo,
68         napi_value &result);
69     static napi_status SetDeviceDescriptor(const napi_env &env, const AudioStandard::AudioDeviceDescriptor &deviceInfo,
70         napi_value &result);
71     static napi_status SetDeviceDescriptors(const napi_env &env,
72         const std::vector<sptr<AudioStandard::AudioDeviceDescriptor>> &deviceDescriptors, napi_value &result);
73 };
74 
75 class MediaJsResult {
76 public:
77     virtual ~MediaJsResult() = default;
78     virtual napi_status GetJsResult(napi_env env, napi_value &result) = 0;
79 };
80 
81 class MediaJsResultBoolean : public MediaJsResult {
82 public:
MediaJsResultBoolean(bool value)83     explicit MediaJsResultBoolean(bool value)
84         : value_(value)
85     {
86     }
87     ~MediaJsResultBoolean() = default;
GetJsResult(napi_env env,napi_value & result)88     napi_status GetJsResult(napi_env env, napi_value &result) override
89     {
90         return napi_get_boolean(env, value_, &result);
91     }
92 private:
93     bool value_;
94 };
95 
96 class MediaJsResultInt : public MediaJsResult {
97 public:
MediaJsResultInt(int32_t value)98     explicit MediaJsResultInt(int32_t value)
99         : value_(value)
100     {
101     }
102     ~MediaJsResultInt() = default;
GetJsResult(napi_env env,napi_value & result)103     napi_status GetJsResult(napi_env env, napi_value &result) override
104     {
105         return napi_create_int32(env, value_, &result);
106     }
107 private:
108     int32_t value_;
109 };
110 
111 class MediaJsResultString : public MediaJsResult {
112 public:
MediaJsResultString(const std::string & value)113     explicit MediaJsResultString(const std::string &value)
114         : value_(value)
115     {
116     }
117     ~MediaJsResultString() = default;
GetJsResult(napi_env env,napi_value & result)118     napi_status GetJsResult(napi_env env, napi_value &result) override
119     {
120         return napi_create_string_utf8(env, value_.c_str(), NAPI_AUTO_LENGTH, &result);
121     }
122 
123 private:
124     std::string value_;
125 };
126 
127 class MediaJsResultStringVector : public MediaJsResult {
128 public:
MediaJsResultStringVector(const std::vector<std::string> & value)129     explicit MediaJsResultStringVector(const std::vector<std::string> &value)
130         : value_(value)
131     {
132     }
133     ~MediaJsResultStringVector() = default;
134     napi_status GetJsResult(napi_env env, napi_value &result) override;
135 
136 private:
137     std::vector<std::string> value_;
138 };
139 
140 class MediaJsResultArray : public MediaJsResult {
141 public:
MediaJsResultArray(const std::vector<Format> & value)142     explicit MediaJsResultArray(const std::vector<Format> &value)
143         : value_(value)
144     {
145     }
146     ~MediaJsResultArray() = default;
147     napi_status GetJsResult(napi_env env, napi_value &result) override;
148 
149 private:
150     std::vector<Format> value_;
151 };
152 
153 class MediaJsResultRange : public MediaJsResult {
154 public:
MediaJsResultRange(int32_t min,int32_t max)155     explicit MediaJsResultRange(int32_t min, int32_t max)
156         : min_(min),
157           max_(max)
158     {
159     }
160     ~MediaJsResultRange() = default;
GetJsResult(napi_env env,napi_value & result)161     napi_status GetJsResult(napi_env env, napi_value &result) override
162     {
163         napi_status status = napi_create_object(env, &result);
164         if (status != napi_ok) {
165             return status;
166         }
167 
168         if (!CommonNapi::SetPropertyInt32(env, result, "min", min_)) {
169             return napi_invalid_arg;
170         }
171 
172         if (!CommonNapi::SetPropertyInt32(env, result, "max", max_)) {
173             return napi_invalid_arg;
174         }
175 
176         return napi_ok;
177     }
178 private:
179     int32_t min_;
180     int32_t max_;
181 };
182 
183 class MediaJsResultInstance : public MediaJsResult {
184 public:
MediaJsResultInstance(const napi_ref & constructor)185     explicit MediaJsResultInstance(const napi_ref &constructor)
186         : constructor_(constructor)
187     {
188     }
189     ~MediaJsResultInstance() = default;
GetJsResult(napi_env env,napi_value & result)190     napi_status GetJsResult(napi_env env, napi_value &result) override
191     {
192         napi_value constructor = nullptr;
193         napi_status ret = napi_get_reference_value(env, constructor_, &constructor);
194         if (ret != napi_ok || constructor == nullptr) {
195             return ret;
196         }
197         return napi_new_instance(env, constructor, 0, nullptr, &result);
198     }
199 
200 private:
201     napi_ref constructor_;
202 };
203 
204 class AVCodecJsResultCtor : public MediaJsResult {
205 public:
AVCodecJsResultCtor(const napi_ref & constructor,int32_t isMimeType,const std::string & name)206     AVCodecJsResultCtor(const napi_ref &constructor, int32_t isMimeType, const std::string &name)
207         : constructor_(constructor),
208           isMimeType_(isMimeType),
209           name_(name)
210     {
211     }
212     ~AVCodecJsResultCtor() = default;
GetJsResult(napi_env env,napi_value & result)213     napi_status GetJsResult(napi_env env, napi_value &result) override
214     {
215         napi_value constructor = nullptr;
216         napi_status ret = napi_get_reference_value(env, constructor_, &constructor);
217         if (ret != napi_ok || constructor == nullptr) {
218             return ret;
219         }
220 
221         napi_value args[2] = { nullptr };
222         ret = napi_create_string_utf8(env, name_.c_str(), NAPI_AUTO_LENGTH, &args[0]);
223         if (ret != napi_ok) {
224             return ret;
225         }
226 
227         ret = napi_create_int32(env, isMimeType_, &args[1]);
228         if (ret != napi_ok) {
229             return ret;
230         }
231 
232         return napi_new_instance(env, constructor, 2, args, &result); // The number of parameters is 2
233     }
234 
235 private:
236     napi_ref constructor_;
237     int32_t isMimeType_ = 0;
238     std::string name_ = "";
239 };
240 
241 class AVCodecJsResultFormat : public MediaJsResult {
242 public:
AVCodecJsResultFormat(const Format & format)243     explicit AVCodecJsResultFormat(const Format &format)
244         : format_(format)
245     {
246     }
247     ~AVCodecJsResultFormat() = default;
GetJsResult(napi_env env,napi_value & result)248     napi_status GetJsResult(napi_env env, napi_value &result) override
249     {
250         (void)CommonNapi::CreateFormatBufferByRef(env, format_, result);
251         return napi_ok;
252     }
253 
254 private:
255     Format format_;
256 };
257 
258 struct MediaAsyncContext {
259     explicit MediaAsyncContext(napi_env env);
260     virtual ~MediaAsyncContext();
261     static void CompleteCallback(napi_env env, napi_status status, void *data);
262     static void Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args);
263     static void CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args);
264     void SignError(int32_t code, const std::string &message, bool del = true);
265     std::string memoryTagHead = "safe";
266     napi_env env_;
267     napi_async_work work = nullptr;
268     napi_deferred deferred = nullptr;
269     napi_ref callbackRef = nullptr;
270     std::unique_ptr<MediaJsResult> JsResult;
271     bool errFlag = false;
272     int32_t errCode = 0;
273     std::string errMessage = "";
274     bool delFlag = true;
275     bool ctorFlag = false;
276     std::string memoryTagTail = "memory";
277 };
278 
279 struct AutoRef {
AutoRefAutoRef280     AutoRef(napi_env env, napi_ref cb)
281         : env_(env), cb_(cb)
282     {
283     }
~AutoRefAutoRef284     ~AutoRef()
285     {
286         if (env_ != nullptr && cb_ != nullptr) {
287             (void)napi_delete_reference(env_, cb_);
288         }
289     }
290     napi_env env_;
291     napi_ref cb_;
292 };
293 
294 struct AVDataSrcDescriptor {
295     int64_t fileSize = 0;
296     napi_value callback = nullptr;
297 };
298 
299 template<typename T>
300 class ObjectRefMap {
301 public:
302     static std::mutex allObjLock;
303     static std::map<T*, uint32_t> refMap;
304     static void Insert(T *obj);
305     static void Erase(T *obj);
306     static T *IncreaseRef(T *obj);
307     static void DecreaseRef(T *obj);
308 
309     ObjectRefMap(T *obj);
310     ~ObjectRefMap();
311     T *GetPtr();
312 
313 private:
314     T *obj_ = nullptr;
315 };
316 
317 template <typename T>
318 std::mutex ObjectRefMap<T>::allObjLock;
319 
320 template <typename T>
321 std::map<T *, uint32_t> ObjectRefMap<T>::refMap;
322 
323 template <typename T>
Insert(T * obj)324 void ObjectRefMap<T>::Insert(T *obj)
325 {
326     std::lock_guard<std::mutex> lock(allObjLock);
327     refMap[obj] = 1;
328 }
329 
330 template <typename T>
Erase(T * obj)331 void ObjectRefMap<T>::Erase(T *obj)
332 {
333     std::lock_guard<std::mutex> lock(allObjLock);
334     auto it = refMap.find(obj);
335     if (it != refMap.end()) {
336         refMap.erase(it);
337     }
338 }
339 
340 template <typename T>
IncreaseRef(T * obj)341 T *ObjectRefMap<T>::IncreaseRef(T *obj)
342 {
343     std::lock_guard<std::mutex> lock(allObjLock);
344     if (refMap.count(obj)) {
345         refMap[obj]++;
346         return obj;
347     } else {
348         return nullptr;
349     }
350 }
351 
352 template <typename T>
DecreaseRef(T * obj)353 void ObjectRefMap<T>::DecreaseRef(T *obj)
354 {
355     std::lock_guard<std::mutex> lock(allObjLock);
356     if (refMap.count(obj) && --refMap[obj] == 0) {
357         refMap.erase(obj);
358         delete obj;
359         obj = nullptr;
360     }
361 }
362 
363 template <typename T>
ObjectRefMap(T * obj)364 ObjectRefMap<T>::ObjectRefMap(T *obj)
365 {
366     if (obj != nullptr) {
367         obj_ = ObjectRefMap::IncreaseRef(obj);
368     }
369 }
370 
371 template <typename T>
~ObjectRefMap()372 ObjectRefMap<T>::~ObjectRefMap()
373 {
374     if (obj_ != nullptr) {
375         ObjectRefMap::DecreaseRef(obj_);
376     }
377 }
378 
379 template <typename T>
GetPtr()380 T *ObjectRefMap<T>::GetPtr()
381 {
382     return obj_;
383 }
384 
385 } // namespace Media
386 } // namespace OHOS
387 #endif // COMMON_NAPI_H
388