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 "format.h" 23 #include "avcontainer_common.h" 24 #include "napi/native_api.h" 25 #include "napi/native_node_api.h" 26 27 namespace OHOS { 28 namespace Media { 29 struct AVFileDescriptor; 30 31 class CommonNapi { 32 public: 33 CommonNapi() = delete; 34 ~CommonNapi() = delete; 35 static std::string GetStringArgument(napi_env env, napi_value value); 36 static bool GetPropertyInt32(napi_env env, napi_value configObj, const std::string &type, int32_t &result); 37 static bool GetPropertyUint32(napi_env env, napi_value configObj, const std::string &type, uint32_t &result); 38 static bool GetPropertyInt64(napi_env env, napi_value configObj, const std::string &type, int64_t &result); 39 static bool GetPropertyDouble(napi_env env, napi_value configObj, const std::string &type, double &result); 40 static std::string GetPropertyString(napi_env env, napi_value configObj, const std::string &type); 41 static bool GetFdArgument(napi_env env, napi_value value, AVFileDescriptor &rawFd); 42 static napi_status FillErrorArgs(napi_env env, int32_t errCode, const napi_value &args); 43 static napi_status CreateError(napi_env env, int32_t errCode, const std::string &errMsg, napi_value &errVal); 44 static napi_ref CreateReference(napi_env env, napi_value arg); 45 static napi_deferred CreatePromise(napi_env env, napi_ref ref, napi_value &result); 46 static bool SetPropertyInt32(napi_env env, napi_value &obj, const std::string &key, int32_t value); 47 static bool SetPropertyString(napi_env env, napi_value &obj, const std::string &key, const std::string &value); 48 static napi_value CreateFormatBuffer(napi_env env, Format &format); 49 static bool CreateFormatBufferByRef(napi_env env, Format &format, napi_value &result); 50 static bool AddRangeProperty(napi_env env, napi_value obj, const std::string &name, int32_t min, int32_t max); 51 static bool AddArrayProperty(napi_env env, napi_value obj, const std::string &name, 52 const std::vector<int32_t> &vec); 53 static bool AddNumberPropInt32(napi_env env, napi_value obj, const std::string &key, int32_t value); 54 static bool AddNumberPropInt64(napi_env env, napi_value obj, const std::string &key, int64_t value); 55 static bool AddArrayInt(napi_env env, napi_value &array, const std::vector<int32_t> &vec); 56 static bool AddStringProperty(napi_env env, napi_value obj, const std::string &key, const std::string &value); 57 }; 58 59 class MediaJsResult { 60 public: 61 virtual ~MediaJsResult() = default; 62 virtual napi_status GetJsResult(napi_env env, napi_value &result) = 0; 63 }; 64 65 class MediaJsResultBoolean : public MediaJsResult { 66 public: MediaJsResultBoolean(bool value)67 explicit MediaJsResultBoolean(bool value) 68 : value_(value) 69 { 70 } 71 ~MediaJsResultBoolean() = default; GetJsResult(napi_env env,napi_value & result)72 napi_status GetJsResult(napi_env env, napi_value &result) override 73 { 74 return napi_get_boolean(env, value_, &result); 75 } 76 private: 77 bool value_; 78 }; 79 80 class MediaJsResultInt : public MediaJsResult { 81 public: MediaJsResultInt(int32_t value)82 explicit MediaJsResultInt(int32_t value) 83 : value_(value) 84 { 85 } 86 ~MediaJsResultInt() = default; GetJsResult(napi_env env,napi_value & result)87 napi_status GetJsResult(napi_env env, napi_value &result) override 88 { 89 return napi_create_int32(env, value_, &result); 90 } 91 private: 92 int32_t value_; 93 }; 94 95 class MediaJsResultString : public MediaJsResult { 96 public: MediaJsResultString(const std::string & value)97 explicit MediaJsResultString(const std::string &value) 98 : value_(value) 99 { 100 } 101 ~MediaJsResultString() = default; GetJsResult(napi_env env,napi_value & result)102 napi_status GetJsResult(napi_env env, napi_value &result) override 103 { 104 return napi_create_string_utf8(env, value_.c_str(), NAPI_AUTO_LENGTH, &result); 105 } 106 107 private: 108 std::string value_; 109 }; 110 111 class MediaJsResultStringVector : public MediaJsResult { 112 public: MediaJsResultStringVector(const std::vector<std::string> & value)113 explicit MediaJsResultStringVector(const std::vector<std::string> &value) 114 : value_(value) 115 { 116 } 117 ~MediaJsResultStringVector() = default; 118 napi_status GetJsResult(napi_env env, napi_value &result) override; 119 120 private: 121 std::vector<std::string> value_; 122 }; 123 124 class MediaJsResultArray : public MediaJsResult { 125 public: MediaJsResultArray(const std::vector<Format> & value)126 explicit MediaJsResultArray(const std::vector<Format> &value) 127 : value_(value) 128 { 129 } 130 ~MediaJsResultArray() = default; 131 napi_status GetJsResult(napi_env env, napi_value &result) override; 132 133 private: 134 std::vector<Format> value_; 135 }; 136 137 class MediaJsResultRange : public MediaJsResult { 138 public: MediaJsResultRange(int32_t min,int32_t max)139 explicit MediaJsResultRange(int32_t min, int32_t max) 140 : min_(min), 141 max_(max) 142 { 143 } 144 ~MediaJsResultRange() = default; GetJsResult(napi_env env,napi_value & result)145 napi_status GetJsResult(napi_env env, napi_value &result) override 146 { 147 napi_status status = napi_create_object(env, &result); 148 if (status != napi_ok) { 149 return status; 150 } 151 152 if (!CommonNapi::SetPropertyInt32(env, result, "min", min_)) { 153 return napi_invalid_arg; 154 } 155 156 if (!CommonNapi::SetPropertyInt32(env, result, "max", max_)) { 157 return napi_invalid_arg; 158 } 159 160 return napi_ok; 161 } 162 private: 163 int32_t min_; 164 int32_t max_; 165 }; 166 167 class MediaJsResultInstance : public MediaJsResult { 168 public: MediaJsResultInstance(const napi_ref & constructor)169 explicit MediaJsResultInstance(const napi_ref &constructor) 170 : constructor_(constructor) 171 { 172 } 173 ~MediaJsResultInstance() = default; GetJsResult(napi_env env,napi_value & result)174 napi_status GetJsResult(napi_env env, napi_value &result) override 175 { 176 napi_value constructor = nullptr; 177 napi_status ret = napi_get_reference_value(env, constructor_, &constructor); 178 if (ret != napi_ok || constructor == nullptr) { 179 return ret; 180 } 181 return napi_new_instance(env, constructor, 0, nullptr, &result); 182 } 183 184 private: 185 napi_ref constructor_; 186 }; 187 188 class AVCodecJsResultCtor : public MediaJsResult { 189 public: AVCodecJsResultCtor(const napi_ref & constructor,int32_t isMimeType,const std::string & name)190 AVCodecJsResultCtor(const napi_ref &constructor, int32_t isMimeType, const std::string &name) 191 : constructor_(constructor), 192 isMimeType_(isMimeType), 193 name_(name) 194 { 195 } 196 ~AVCodecJsResultCtor() = default; GetJsResult(napi_env env,napi_value & result)197 napi_status GetJsResult(napi_env env, napi_value &result) override 198 { 199 napi_value constructor = nullptr; 200 napi_status ret = napi_get_reference_value(env, constructor_, &constructor); 201 if (ret != napi_ok || constructor == nullptr) { 202 return ret; 203 } 204 205 napi_value args[2] = { nullptr }; 206 ret = napi_create_string_utf8(env, name_.c_str(), NAPI_AUTO_LENGTH, &args[0]); 207 if (ret != napi_ok) { 208 return ret; 209 } 210 211 ret = napi_create_int32(env, isMimeType_, &args[1]); 212 if (ret != napi_ok) { 213 return ret; 214 } 215 216 return napi_new_instance(env, constructor, 2, args, &result); // The number of parameters is 2 217 } 218 219 private: 220 napi_ref constructor_; 221 int32_t isMimeType_ = 0; 222 std::string name_ = ""; 223 }; 224 225 class AVCodecJsResultFormat : public MediaJsResult { 226 public: AVCodecJsResultFormat(const Format & format)227 explicit AVCodecJsResultFormat(const Format &format) 228 : format_(format) 229 { 230 } 231 ~AVCodecJsResultFormat() = default; GetJsResult(napi_env env,napi_value & result)232 napi_status GetJsResult(napi_env env, napi_value &result) override 233 { 234 (void)CommonNapi::CreateFormatBufferByRef(env, format_, result); 235 return napi_ok; 236 } 237 238 private: 239 Format format_; 240 }; 241 242 struct MediaAsyncContext { 243 explicit MediaAsyncContext(napi_env env); 244 virtual ~MediaAsyncContext(); 245 static void CompleteCallback(napi_env env, napi_status status, void *data); 246 static void Callback(napi_env env, const MediaAsyncContext *context, const napi_value *args); 247 static void CheckCtorResult(napi_env env, napi_value &result, MediaAsyncContext *ctx, napi_value &args); 248 void SignError(int32_t code, const std::string &message, bool del = true); 249 std::string memoryTagHead = "safe"; 250 napi_env env_; 251 napi_async_work work = nullptr; 252 napi_deferred deferred = nullptr; 253 napi_ref callbackRef = nullptr; 254 std::unique_ptr<MediaJsResult> JsResult; 255 bool errFlag = false; 256 int32_t errCode = 0; 257 std::string errMessage = ""; 258 bool delFlag = true; 259 bool ctorFlag = false; 260 std::string memoryTagTail = "memory"; 261 }; 262 263 struct AutoRef { AutoRefAutoRef264 AutoRef(napi_env env, napi_ref cb) 265 : env_(env), cb_(cb) 266 { 267 } ~AutoRefAutoRef268 ~AutoRef() 269 { 270 if (env_ != nullptr && cb_ != nullptr) { 271 (void)napi_delete_reference(env_, cb_); 272 } 273 } 274 napi_env env_; 275 napi_ref cb_; 276 }; 277 278 struct AVFileDescriptor { 279 int32_t fd = 0; 280 int64_t offset = 0; 281 int64_t length = -1; 282 }; 283 } // namespace Media 284 } // namespace OHOS 285 #endif // COMMON_NAPI_H 286