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