1 /* 2 * Copyright (C) 2024-2025 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 = INT32_MAX; 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_CODEC_FORMAT_BUTT; 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 bool enableBFrame = false; 114 }; 115 116 using RetInfo = std::pair<int32_t, std::string>; 117 118 class AVTransCoderNapi { 119 public: 120 __attribute__((visibility("default"))) static napi_value Init(napi_env env, napi_value exports); 121 122 using AvTransCoderTaskqFunc = RetInfo (AVTransCoderNapi::*)(); 123 124 private: 125 static napi_value Constructor(napi_env env, napi_callback_info info); 126 static void Destructor(napi_env env, void *nativeObject, void *finalize); 127 /** 128 * createAVTransCoder(): Promise<VideoPlayer> 129 */ 130 static napi_value JsCreateAVTransCoder(napi_env env, napi_callback_info info); 131 /** 132 * prepare(config: AVTransCoderConfig): Promise<void>; 133 */ 134 static napi_value JsPrepare(napi_env env, napi_callback_info info); 135 /** 136 * start(): Promise<void>; 137 */ 138 static napi_value JsStart(napi_env env, napi_callback_info info); 139 /** 140 * pause(): Promise<void>; 141 */ 142 static napi_value JsPause(napi_env env, napi_callback_info info); 143 /** 144 * resume(): Promise<void>; 145 */ 146 static napi_value JsResume(napi_env env, napi_callback_info info); 147 /** 148 * cancel(): Promise<void>; 149 */ 150 static napi_value JsCancel(napi_env env, napi_callback_info info); 151 /** 152 * release(): Promise<void> 153 */ 154 static napi_value JsRelease(napi_env env, napi_callback_info info); 155 /** 156 * on(type: 'complete', callback: Callback<void>): void 157 * on(type: 'error', callback: ErrorCallback): void 158 * on(type: 'progressUpdate', callback: Callback<number>): void 159 */ 160 static napi_value JsSetEventCallback(napi_env env, napi_callback_info info); 161 /** 162 * off(type: 'complete'): void; 163 * off(type: 'error'): void; 164 * off(type: 'progressUpdate'): void 165 */ 166 static napi_value JsCancelEventCallback(napi_env env, napi_callback_info info); 167 168 /** 169 * srcUrl: string 170 */ 171 static napi_value JsGetSrcUrl(napi_env env, napi_callback_info info); 172 173 static napi_value JsSetSrcFd(napi_env env, napi_callback_info info); 174 static napi_value JsGetSrcFd(napi_env env, napi_callback_info info); 175 176 static napi_value JsSetDstFd(napi_env env, napi_callback_info info); 177 static napi_value JsGetDstFd(napi_env env, napi_callback_info info); 178 179 static AVTransCoderNapi* GetJsInstanceAndArgs(napi_env env, napi_callback_info info, 180 size_t &argCount, napi_value *args); 181 static napi_value ExecuteByPromise(napi_env env, napi_callback_info info, const std::string &opt); 182 static std::shared_ptr<TaskHandler<RetInfo>> GetPrepareTask(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx); 183 static std::shared_ptr<TaskHandler<RetInfo>> GetPromiseTask(AVTransCoderNapi *avnapi, const std::string &opt); 184 185 static int32_t GetAudioCodecFormat(const std::string &mime, AudioCodecFormat &codecFormat); 186 static int32_t GetVideoCodecFormat(const std::string &mime, VideoCodecFormat &codecFormat); 187 static int32_t GetOutputFormat(const std::string &extension, OutputFormatType &type); 188 189 AVTransCoderNapi(); 190 ~AVTransCoderNapi(); 191 192 RetInfo Start(); 193 RetInfo Pause(); 194 RetInfo Resume(); 195 RetInfo Cancel(); 196 RetInfo Release(); 197 198 RetInfo SetInputFile(int32_t fd, int64_t offset, int64_t size); 199 RetInfo SetOutputFile(int32_t fd); 200 201 int32_t CheckStateMachine(const std::string &opt); 202 int32_t CheckRepeatOperation(const std::string &opt); 203 204 void ErrorCallback(int32_t errCode, const std::string &operate, const std::string &add = ""); 205 void StateCallback(const std::string &state); 206 void SetCallbackReference(const std::string &callbackName, std::shared_ptr<AutoRef> ref); 207 void CancelCallbackReference(const std::string &callbackName); 208 void CancelCallback(); 209 210 RetInfo Configure(std::shared_ptr<AVTransCoderConfig> config); 211 int32_t GetAudioConfig(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx, napi_env env, napi_value args); 212 int32_t GetVideoConfig(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx, napi_env env, napi_value args); 213 int32_t GetConfig(std::unique_ptr<AVTransCoderAsyncContext> &asyncCtx, napi_env env, napi_value args); 214 215 static thread_local napi_ref constructor_; 216 napi_env env_ = nullptr; 217 std::shared_ptr<TransCoder> transCoder_ = nullptr; 218 std::shared_ptr<TransCoderCallback> transCoderCb_ = nullptr; 219 std::map<std::string, std::shared_ptr<AutoRef>> eventCbMap_; 220 std::unique_ptr<TaskQueue> taskQue_; 221 static std::map<std::string, AvTransCoderTaskqFunc> taskQFuncs_; 222 bool hasConfiged_ = false; 223 224 std::string srcUrl_ = ""; 225 struct AVFileDescriptor srcFd_; 226 int32_t dstFd_ = -1; 227 }; 228 229 struct AVTransCoderAsyncContext : public MediaAsyncContext { AVTransCoderAsyncContextAVTransCoderAsyncContext230 explicit AVTransCoderAsyncContext(napi_env env) : MediaAsyncContext(env) {} 231 ~AVTransCoderAsyncContext() = default; 232 233 void AVTransCoderSignError(int32_t errCode, const std::string &operate, 234 const std::string ¶m, const std::string &add = ""); 235 236 AVTransCoderNapi *napi = nullptr; 237 std::shared_ptr<AVTransCoderConfig> config_ = nullptr; 238 std::string opt_ = ""; 239 std::shared_ptr<TaskHandler<RetInfo>> task_ = nullptr; 240 }; 241 242 class MediaJsAVTransCoderConfig : public MediaJsResult { 243 public: MediaJsAVTransCoderConfig(std::shared_ptr<AVTransCoderConfig> value)244 explicit MediaJsAVTransCoderConfig(std::shared_ptr<AVTransCoderConfig> value) 245 : value_(value) 246 { 247 } 248 ~MediaJsAVTransCoderConfig() = default; 249 250 private: 251 std::shared_ptr<AVTransCoderConfig> value_ = nullptr; 252 }; 253 254 } // namespace Media 255 } // namespace OHOS 256 #endif // AV_RECORDER_NAPI_H