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