1 /* 2 * Copyright (C) 2024 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 AV_TRANSCODER_NAPI_H 17 #define AV_TRANSCODER_NAPI_H 18 19 #include "av_common.h" 20 #include "media_errors.h" 21 #include "napi/native_api.h" 22 #include "napi/native_node_api.h" 23 #include "common_napi.h" 24 #include "task_queue.h" 25 #include "transcoder.h" 26 27 namespace OHOS { 28 namespace Media { 29 namespace AVTransCoderState { 30 const std::string STATE_IDLE = "idle"; 31 const std::string STATE_PREPARED = "prepared"; 32 const std::string STATE_STARTED = "started"; 33 const std::string STATE_PAUSED = "paused"; 34 const std::string STATE_CANCELLED = "cancelled"; 35 const std::string STATE_COMPLETED = "completed"; 36 const std::string STATE_RELEASED = "released"; 37 const std::string STATE_ERROR = "error"; 38 } 39 40 namespace AVTransCoderOpt { 41 const std::string PREPARE = "Prepare"; 42 const std::string START = "Start"; 43 const std::string PAUSE = "Pause"; 44 const std::string RESUME = "Resume"; 45 const std::string CANCEL = "Cancel"; 46 const std::string RELEASE = "Release"; 47 const std::string SET_AV_TRANSCODER_CONFIG = "SetAVTransCoderConfig"; 48 } 49 50 constexpr int32_t AVTRANSCODER_DEFAULT_AUDIO_BIT_RATE = 48000; 51 constexpr int32_t AVTRANSCODER_DEFAULT_VIDEO_BIT_RATE = -1; 52 constexpr int32_t AVTRANSCODER_DEFAULT_FRAME_HEIGHT = -1; 53 constexpr int32_t AVTRANSCODER_DEFAULT_FRAME_WIDTH = -1; 54 55 const std::map<std::string, std::vector<std::string>> STATE_LIST = { 56 {AVTransCoderState::STATE_IDLE, { 57 AVTransCoderOpt::PREPARE, 58 AVTransCoderOpt::RELEASE 59 }}, 60 {AVTransCoderState::STATE_PREPARED, { 61 AVTransCoderOpt::START, 62 AVTransCoderOpt::RELEASE 63 }}, 64 {AVTransCoderState::STATE_STARTED, { 65 AVTransCoderOpt::START, 66 AVTransCoderOpt::PAUSE, 67 AVTransCoderOpt::RESUME, 68 AVTransCoderOpt::CANCEL, 69 AVTransCoderOpt::RELEASE 70 }}, 71 {AVTransCoderState::STATE_PAUSED, { 72 AVTransCoderOpt::START, 73 AVTransCoderOpt::PAUSE, 74 AVTransCoderOpt::RESUME, 75 AVTransCoderOpt::CANCEL, 76 AVTransCoderOpt::RELEASE 77 }}, 78 {AVTransCoderState::STATE_CANCELLED, { 79 AVTransCoderOpt::RELEASE 80 }}, 81 {AVTransCoderState::STATE_COMPLETED, { 82 AVTransCoderOpt::RELEASE 83 }}, 84 {AVTransCoderState::STATE_RELEASED, { 85 AVTransCoderOpt::RELEASE 86 }}, 87 {AVTransCoderState::STATE_ERROR, { 88 AVTransCoderOpt::RELEASE 89 }}, 90 }; 91 92 /** 93 * on(type: 'complete', callback: Callback<void>): void 94 * on(type: 'error', callback: ErrorCallback): void 95 * on(type: 'progressUpdate', callback: Callback<number>): void 96 */ 97 namespace AVTransCoderEvent { 98 const std::string EVENT_COMPLETE = "complete"; 99 const std::string EVENT_ERROR = "error"; 100 const std::string EVENT_PROGRESS_UPDATE = "progressUpdate"; 101 } 102 103 struct AVTransCoderAsyncContext; 104 105 struct AVTransCoderConfig { 106 AudioCodecFormat audioCodecFormat = AudioCodecFormat::AUDIO_DEFAULT; 107 int32_t audioBitrate = AVTRANSCODER_DEFAULT_AUDIO_BIT_RATE; 108 OutputFormatType fileFormat = OutputFormatType::FORMAT_DEFAULT; 109 VideoCodecFormat videoCodecFormat = VideoCodecFormat::VIDEO_DEFAULT; 110 int32_t videoBitrate = AVTRANSCODER_DEFAULT_VIDEO_BIT_RATE; 111 int32_t videoFrameWidth = AVTRANSCODER_DEFAULT_FRAME_HEIGHT; 112 int32_t videoFrameHeight = AVTRANSCODER_DEFAULT_FRAME_WIDTH; 113 }; 114 115 using RetInfo = std::pair<int32_t, std::string>; 116 117 class AVTransCoderNapi { 118 public: 119 __attribute__((visibility("default"))) static napi_value Init(napi_env env, napi_value exports); 120 121 using AvTransCoderTaskqFunc = RetInfo (AVTransCoderNapi::*)(); 122 123 private: 124 static napi_value Constructor(napi_env env, napi_callback_info info); 125 static void Destructor(napi_env env, void *nativeObject, void *finalize); 126 /** 127 * createAVTransCoder(): Promise<VideoPlayer> 128 */ 129 static napi_value JsCreateAVTransCoder(napi_env env, napi_callback_info info); 130 /** 131 * prepare(config: AVTransCoderConfig): Promise<void>; 132 */ 133 static napi_value JsPrepare(napi_env env, napi_callback_info info); 134 /** 135 * start(): Promise<void>; 136 */ 137 static napi_value JsStart(napi_env env, napi_callback_info info); 138 /** 139 * pause(): Promise<void>; 140 */ 141 static napi_value JsPause(napi_env env, napi_callback_info info); 142 /** 143 * resume(): Promise<void>; 144 */ 145 static napi_value JsResume(napi_env env, napi_callback_info info); 146 /** 147 * cancel(): Promise<void>; 148 */ 149 static napi_value JsCancel(napi_env env, napi_callback_info info); 150 /** 151 * release(): Promise<void> 152 */ 153 static napi_value JsRelease(napi_env env, napi_callback_info info); 154 /** 155 * on(type: 'complete', callback: Callback<void>): void 156 * on(type: 'error', callback: ErrorCallback): void 157 * on(type: 'progressUpdate', callback: Callback<number>): void 158 */ 159 static napi_value JsSetEventCallback(napi_env env, napi_callback_info info); 160 /** 161 * off(type: 'complete'): void; 162 * off(type: 'error'): void; 163 * off(type: 'progressUpdate'): void 164 */ 165 static napi_value JsCancelEventCallback(napi_env env, napi_callback_info info); 166 167 /** 168 * srcUrl: string 169 */ 170 static napi_value JsGetSrcUrl(napi_env env, napi_callback_info info); 171 172 static napi_value JsSetSrcFd(napi_env env, napi_callback_info info); 173 static napi_value JsGetSrcFd(napi_env env, napi_callback_info info); 174 175 static napi_value JsSetDstFd(napi_env env, napi_callback_info info); 176 static napi_value JsGetDstFd(napi_env env, napi_callback_info info); 177 178 static AVTransCoderNapi* GetJsInstanceAndArgs(napi_env env, napi_callback_info info, 179 size_t &argCount, napi_value *args); 180 static napi_value ExecuteByPromise(napi_env env, napi_callback_info info, const std::string &opt); 181 static std::shared_ptr<TaskHandler<RetInfo>> GetPrepareTask(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx); 182 static std::shared_ptr<TaskHandler<RetInfo>> GetPromiseTask(AVTransCoderNapi *avnapi, const std::string &opt); 183 184 static int32_t GetAudioCodecFormat(const std::string &mime, AudioCodecFormat &codecFormat); 185 static int32_t GetVideoCodecFormat(const std::string &mime, VideoCodecFormat &codecFormat); 186 static int32_t GetOutputFormat(const std::string &extension, OutputFormatType &type); 187 188 AVTransCoderNapi(); 189 ~AVTransCoderNapi(); 190 191 RetInfo Start(); 192 RetInfo Pause(); 193 RetInfo Resume(); 194 RetInfo Cancel(); 195 RetInfo Release(); 196 197 RetInfo SetInputFile(int32_t fd, int64_t offset, int64_t size); 198 RetInfo SetOutputFile(int32_t fd); 199 200 int32_t CheckStateMachine(const std::string &opt); 201 int32_t CheckRepeatOperation(const std::string &opt); 202 203 void ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add = ""); 204 void StateCallback(const std::string &state); 205 void SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref); 206 void CancelCallbackReference(const std::string &callbackName); 207 void CancelCallback(); 208 209 RetInfo Configure(std::shared_ptr<AVTransCoderConfig> config); 210 int32_t GetAudioConfig(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx, napi_env env, napi_value args); 211 int32_t GetVideoConfig(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx, napi_env env, napi_value args); 212 int32_t GetConfig(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx, napi_env env, napi_value args); 213 214 static thread_local napi_ref constructor_; 215 napi_env env_ = nullptr; 216 std::shared_ptr<TransCoder> transCoder_ = nullptr; 217 std::shared_ptr<TransCoderCallback> transCoderCb_ = nullptr; 218 std::map<std::string, std::shared_ptr<AutoRef>> eventCbMap_; 219 std::unique_ptr<TaskQueue> taskQue_; 220 static std::map<std::string, AvTransCoderTaskqFunc> taskQFuncs_; 221 bool hasConfiged_ = false; 222 223 std::string srcUrl_ = ""; 224 struct AVFileDescriptor srcFd_; 225 int32_t dstFd_ = -1; 226 }; 227 228 struct AVTransCoderAsyncContext : public MediaAsyncContext { AVTransCoderAsyncContextAVTransCoderAsyncContext229 explicit AVTransCoderAsyncContext(napi_env env) : MediaAsyncContext(env) {} 230 ~AVTransCoderAsyncContext() = default; 231 232 void AVTransCoderSignError(int32_t errCode, const std::string &operate, 233 const std::string ¶m, const std::string &add = ""); 234 235 AVTransCoderNapi *napi = nullptr; 236 std::shared_ptr<AVTransCoderConfig> config_ = nullptr; 237 std::string opt_ = ""; 238 std::shared_ptr<TaskHandler<RetInfo>> task_ = nullptr; 239 }; 240 241 class MediaJsAVTransCoderConfig : public MediaJsResult { 242 public: MediaJsAVTransCoderConfig(std::shared_ptr<AVTransCoderConfig> value)243 explicit MediaJsAVTransCoderConfig(std::shared_ptr<AVTransCoderConfig> value) 244 : value_(value) 245 { 246 } 247 ~MediaJsAVTransCoderConfig() = default; 248 249 private: 250 std::shared_ptr<AVTransCoderConfig> value_ = nullptr; 251 }; 252 253 } // namespace Media 254 } // namespace OHOS 255 #endif // AV_RECORDER_NAPI_H