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 #define MLOG_TAG "MediaCallTranscode"
17 
18 #include "media_asset_manager_callback.h"
19 #include "media_call_transcode.h"
20 #include "medialibrary_napi_log.h"
21 #include "medialibrary_errno.h"
22 
23 namespace OHOS {
24 namespace Media {
25 
26 static MediaCallTranscode::CallbackType callback_;
27 static std::map<std::string, std::shared_ptr<TransCoder>> transCoderMap_;
28 static const int32_t INFO_TYPE_ERROR = 2;
TransCodeError(napi_env env, napi_value &result, int srcFd, int destFd, const std::string& errorMsg)29 void MediaCallTranscode::TransCodeError(napi_env env, napi_value &result,
30     int srcFd, int destFd, const std::string& errorMsg)
31 {
32     NAPI_ERR_LOG(" %{public}s", errorMsg.c_str());
33     close(srcFd);
34     close(destFd);
35     napi_get_boolean(env, false, &result);
36 }
37 
CallTranscodeHandle(napi_env env, int srcFd, int destFd, napi_value &result, off_t &size, std::string requestId)38 void MediaCallTranscode::CallTranscodeHandle(napi_env env, int srcFd, int destFd,
39     napi_value &result, off_t &size, std::string requestId)
40 {
41     NAPI_INFO_LOG("CallTranscodeHandle start");
42     auto transCoder = TransCoderFactory::CreateTransCoder();
43     if (transCoder == nullptr) {
44         TransCodeError(env, result, srcFd, destFd, "Failed to create TransCoder");
45         return;
46     }
47     transCoderMap_.insert(std::pair<std::string, std::shared_ptr<TransCoder>>(requestId, transCoder));
48     auto transCoderCb = std::make_shared<OHOS::Media::MediaAssetManagerCallback>();
49     if (transCoderCb == nullptr) {
50         TransCodeError(env, result, srcFd, destFd, "Failed to create MediaAssetManagerCallback");
51         return;
52     }
53     transCoderCb->SetRequestId(requestId);
54     int32_t ret = transCoder->SetTransCoderCallback(transCoderCb);
55     if (ret != E_OK) {
56         TransCodeError(env, result, srcFd, destFd, "Failed to set TransCoder callback");
57         return;
58     }
59     ret = transCoder->SetInputFile(srcFd, 0, size);
60     if (ret != E_OK) {
61         TransCodeError(env, result, srcFd, destFd, "Failed to set input file for TransCoder");
62         return;
63     }
64     ret = transCoder->SetOutputFile(destFd);
65     if (ret != E_OK) {
66         TransCodeError(env, result, srcFd, destFd, "Failed to set output file for TransCoder");
67         return;
68     }
69     ret = transCoder->SetOutputFormat(FORMAT_MPEG_4);
70     if (ret != E_OK) {
71         TransCodeError(env, result, srcFd, destFd, "Failed to SetOutputFormat");
72         return;
73     }
74     ret = transCoder->Prepare();
75     if (ret != E_OK) {
76         TransCodeError(env, result, srcFd, destFd, "Failed to prepare TransCoder");
77         return;
78     }
79     ret = transCoder->Start();
80     if (ret != E_OK) {
81         TransCodeError(env, result, srcFd, destFd, "Failed to TransCoder Start");
82         return;
83     }
84     napi_get_boolean(env, true, &result);
85 }
86 
CallTranscodeRelease(const std::string& requestId)87 void MediaCallTranscode::CallTranscodeRelease(const std::string& requestId)
88 {
89     auto tcm = transCoderMap_.find(requestId);
90     if (tcm == transCoderMap_.end()) {
91         return;
92     }
93     tcm->second->Release();
94     transCoderMap_.erase(tcm);
95 }
96 
RegisterCallback(const CallbackType &cb)97 void MediaCallTranscode::RegisterCallback(const CallbackType &cb)
98 {
99     callback_ = cb;
100 }
101 
OnInfo(int32_t type, int32_t extra)102 void MediaAssetManagerCallback::OnInfo(int32_t type, int32_t extra)
103 {
104     NAPI_INFO_LOG("MediaAssetManagerCallback OnInfo type:%{public}d extra:%{public}d", type, extra);
105     if (callback_) {
106         callback_(type, extra, requestId_);
107     }
108 }
109 
OnError(int32_t errCode, const std::string &errorMsg)110 void MediaAssetManagerCallback::OnError(int32_t errCode, const std::string &errorMsg)
111 {
112     auto tcm = transCoderMap_.find(requestId_);
113     transCoderMap_.erase(tcm);
114     NAPI_ERR_LOG("MediaAssetManagerCallback OnInfo errorMsg:%{public}s", errorMsg.c_str());
115     int32_t type = INFO_TYPE_ERROR;
116     if (callback_) {
117         callback_(type, 0, requestId_);
118     }
119 }
120 
SetRequestId(std::string requestId)121 void MediaAssetManagerCallback::SetRequestId(std::string requestId)
122 {
123     requestId_ = requestId;
124 }
125 } // namespace Media
126 } // namespace OHOS
127