• 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     bool enableCameraPostprocessing {false};
392     int32_t mutedMediaType = static_cast<int32_t>(MediaType::MEDIA_TYPE_MAX_COUNT);
393     std::string preferredAudioLanguage;
394     std::string preferredSubtitleLanguage;
395     double preferredBufferDurationForPlaying {0};
396     double thresholdForAutoQuickPlay {-1};
397     bool isSetBufferDurationForPlaying {false};
398     bool isSetThresholdForAutoQuickPlay {false};
399     bool keepDecodingOnMute {false};
400 };
401 
402 struct AVPlayMediaStreamTmp {
403     std::string url;
404     uint32_t width;
405     uint32_t height;
406     uint32_t bitrate;
407 };
408 
409 template<typename T>
410 class ObjectRefMap {
411 public:
412     static std::mutex allObjLock;
413     static std::map<T*, uint32_t> refMap;
414     static void Insert(T *obj);
415     static void Erase(T *obj);
416     static T *IncreaseRef(T *obj);
417     static void DecreaseRef(T *obj);
418 
419     explicit ObjectRefMap(T *obj);
420     ~ObjectRefMap();
421     T *GetPtr();
422 
423 private:
424     T *obj_ = nullptr;
425 };
426 
427 template <typename T>
428 std::mutex ObjectRefMap<T>::allObjLock;
429 
430 template <typename T>
431 std::map<T *, uint32_t> ObjectRefMap<T>::refMap;
432 
433 template <typename T>
Insert(T * obj)434 void ObjectRefMap<T>::Insert(T *obj)
435 {
436     std::lock_guard<std::mutex> lock(allObjLock);
437     refMap[obj] = 1;
438 }
439 
440 template <typename T>
Erase(T * obj)441 void ObjectRefMap<T>::Erase(T *obj)
442 {
443     std::lock_guard<std::mutex> lock(allObjLock);
444     auto it = refMap.find(obj);
445     if (it != refMap.end()) {
446         refMap.erase(it);
447     }
448 }
449 
450 template <typename T>
IncreaseRef(T * obj)451 T *ObjectRefMap<T>::IncreaseRef(T *obj)
452 {
453     std::lock_guard<std::mutex> lock(allObjLock);
454     if (refMap.count(obj)) {
455         refMap[obj]++;
456         return obj;
457     } else {
458         return nullptr;
459     }
460 }
461 
462 template <typename T>
DecreaseRef(T * obj)463 void ObjectRefMap<T>::DecreaseRef(T *obj)
464 {
465     std::lock_guard<std::mutex> lock(allObjLock);
466     if (refMap.count(obj) && --refMap[obj] == 0) {
467         refMap.erase(obj);
468         delete obj;
469         obj = nullptr;
470     }
471 }
472 
473 template <typename T>
ObjectRefMap(T * obj)474 ObjectRefMap<T>::ObjectRefMap(T *obj)
475 {
476     if (obj != nullptr) {
477         obj_ = ObjectRefMap::IncreaseRef(obj);
478     }
479 }
480 
481 template <typename T>
~ObjectRefMap()482 ObjectRefMap<T>::~ObjectRefMap()
483 {
484     if (obj_ != nullptr) {
485         ObjectRefMap::DecreaseRef(obj_);
486     }
487 }
488 
489 template <typename T>
GetPtr()490 T *ObjectRefMap<T>::GetPtr()
491 {
492     return obj_;
493 }
494 
495 } // namespace Media
496 } // namespace OHOS
497 #endif // COMMON_NAPI_H
498