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 #include "ic_sdk_impl.h"
17
18 #include <algorithm>
19
20 #include "aie_guard.h"
21 #include "aie_retcode_inner.h"
22 #include "encdec_facade.h"
23 #include "i_aie_client.inl"
24 #include "ic_retcode.h"
25 #include "plugin_helper.h"
26
27 using namespace OHOS::AI;
28 namespace {
29 const uint32_t MAX_IPC_BUFFER_SIZE = 25600;
30 }
31
32 IMPLEMENT_SINGLE_INSTANCE(IcSdkImpl);
33
34 IcSdkImpl::IcSdkImpl() = default;
35
36 IcSdkImpl::~IcSdkImpl() = default;
37
Create()38 int32_t IcSdkImpl::Create()
39 {
40 HILOGI("[IcSdkImpl]Start");
41 if (icHandle_ != INVALID_IC_HANDLE) {
42 HILOGE("[IcSdkImpl]Do not create again");
43 return IC_RETCODE_INIT_ERROR;
44 }
45 int32_t retCode = AieClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr);
46 if (retCode != RETCODE_SUCCESS) {
47 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_INIT_ERROR))
48 : HILOGD("[IcSdkImpl]No callback");
49 HILOGE("[IcSdkImpl]AieClientInit failed. Error code[%d]", retCode);
50 return IC_RETCODE_INIT_ERROR;
51 }
52 if (clientInfo_.clientId == INVALID_CLIENT_ID) {
53 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_INIT_ERROR))
54 : HILOGD("[IcSdkImpl]No callback");
55 HILOGE("[IcSdkImpl]Fail to allocate client id");
56 return IC_RETCODE_INIT_ERROR;
57 }
58 DataInfo inputInfo = {.data = nullptr, .length = 0};
59 DataInfo outputInfo = {.data = nullptr, .length = 0};
60 retCode = AieClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr);
61 if (retCode != RETCODE_SUCCESS) {
62 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_INIT_ERROR))
63 : HILOGD("[IcSdkImpl]No callback");
64 HILOGE("[IcSdkImpl]AieClientPrepare failed. Error code[%d]", retCode);
65 return IC_RETCODE_INIT_ERROR;
66 }
67 if (outputInfo.data == nullptr || outputInfo.length <= 0) {
68 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_INIT_ERROR))
69 : HILOGD("[IcSdkImpl]No callback");
70 HILOGE("[IcSdkImpl]The data or length of output info is invalid");
71 return IC_RETCODE_INIT_ERROR;
72 }
73 MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data);
74 retCode = EncdecFacade::ProcessDecode(outputInfo, icHandle_);
75 if (retCode != RETCODE_SUCCESS) {
76 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_UNSERIALIZATION_ERROR))
77 : HILOGD("[IcSdkImpl]No callback");
78 HILOGE("[IcSdkImpl]Failed to UnSerializeHandle");
79 return IC_RETCODE_UNSERIALIZATION_ERROR;
80 }
81 return IC_RETCODE_SUCCESS;
82 }
83
OnSyncExecute(const IcInput & inputData,DataInfo & outputInfo)84 int32_t IcSdkImpl::OnSyncExecute(const IcInput &inputData, DataInfo &outputInfo)
85 {
86 if (inputData.data == nullptr || inputData.size == 0) {
87 HILOGE("[IcSdkImpl]Empty input");
88 return IC_RETCODE_NULL_PARAM;
89 }
90 DataInfo inputInfo = {
91 .data = nullptr,
92 .length = 0
93 };
94 IcInput tmpImage = {
95 .data = nullptr,
96 .size = MAX_IPC_BUFFER_SIZE
97 };
98 uint32_t offset = 0;
99 int32_t retCode = RETCODE_SUCCESS;
100 while (offset < inputData.size) {
101 tmpImage.data = &inputData.data[offset];
102 tmpImage.size = std::min(inputData.size - offset, MAX_IPC_BUFFER_SIZE);
103 inputInfo.data = nullptr;
104 inputInfo.length = 0;
105 outputInfo.data = nullptr;
106 outputInfo.length = 0;
107 retCode = EncdecFacade::ProcessEncode(inputInfo, icHandle_, offset, tmpImage);
108 if (retCode != RETCODE_SUCCESS) {
109 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_SERIALIZATION_ERROR))
110 : HILOGD("[IcSdkImpl]No callback");
111 HILOGE("[IcSdkImpl]Failed to UnSerializeHandle");
112 return IC_RETCODE_SERIALIZATION_ERROR;
113 }
114 retCode = AieClientSyncProcess(clientInfo_, algorithmInfo_, inputInfo, outputInfo);
115 if (retCode != RETCODE_SUCCESS) {
116 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_FAILURE))
117 : HILOGD("[IcSdkImpl]No callback");
118 HILOGE("[IcSdkImpl]SyncExecute AieClientSyncProcess failed");
119 return IC_RETCODE_FAILURE;
120 }
121 offset += tmpImage.size;
122 }
123 return IC_RETCODE_SUCCESS;
124 }
125
SyncExecute(const IcInput & inputData)126 int32_t IcSdkImpl::SyncExecute(const IcInput &inputData)
127 {
128 HILOGI("[IcSdkImpl]Start");
129 DataInfo outputInfo = {.data = nullptr, .length = 0};
130 int32_t retCode = OnSyncExecute(inputData, outputInfo);
131 if (outputInfo.data == nullptr || outputInfo.length <= 0 || retCode != IC_RETCODE_SUCCESS) {
132 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_FAILURE))
133 : HILOGD("[IcSdkImpl]No callback");
134 HILOGE("[IcSdkImpl]SyncExecute failed");
135 return retCode;
136 }
137 IcOutput icResult = {.data = nullptr, .size = 0};
138 intptr_t receivedHandle = INVALID_IC_HANDLE;
139 MallocPointerGuard<unsigned char> pointerGuard(outputInfo.data);
140 retCode = EncdecFacade::ProcessDecode(outputInfo, receivedHandle, icResult);
141 if (retCode != RETCODE_SUCCESS) {
142 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_UNSERIALIZATION_ERROR))
143 : HILOGD("[IcSdkImpl]No callback");
144 HILOGE("[IcSdkImpl]Failed to UnSerializeHandle");
145 return IC_RETCODE_UNSERIALIZATION_ERROR;
146 }
147 if (icHandle_ != receivedHandle) {
148 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_FAILURE))
149 : HILOGD("[IcSdkImpl]No callback");
150 HILOGE("[IcSdkImpl]The handle[%lld] of output data is not equal to the current handle[%lld]",
151 (long long)receivedHandle, (long long)icHandle_);
152 return IC_RETCODE_FAILURE;
153 }
154 (callback_ != nullptr) ? (callback_->OnResult(icResult))
155 : HILOGD("[IcSdkImpl]No callback");
156 return IC_RETCODE_SUCCESS;
157 }
158
SetCallback(std::shared_ptr<IcCallback> callback)159 int32_t IcSdkImpl::SetCallback(std::shared_ptr<IcCallback> callback)
160 {
161 if (callback == nullptr) {
162 return IC_RETCODE_FAILURE;
163 }
164 callback_ = callback;
165 return IC_RETCODE_SUCCESS;
166 }
167
Destroy()168 int32_t IcSdkImpl::Destroy()
169 {
170 HILOGI("[IcSdkImpl]Destroy");
171 if (icHandle_ == INVALID_IC_HANDLE) {
172 return IC_RETCODE_SUCCESS;
173 }
174 DataInfo inputInfo = {.data = nullptr, .length = 0};
175 int32_t retCode = EncdecFacade::ProcessEncode(inputInfo, icHandle_);
176 if (retCode != RETCODE_SUCCESS) {
177 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_SERIALIZATION_ERROR))
178 : HILOGD("[IcSdkImpl]No callback");
179 HILOGE("[IcSdkImpl]Failed to SerializeHandle");
180 return IC_RETCODE_SERIALIZATION_ERROR;
181 }
182 retCode = AieClientRelease(clientInfo_, algorithmInfo_, inputInfo);
183 if (retCode != RETCODE_SUCCESS) {
184 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_FAILURE))
185 : HILOGD("[IcSdkImpl]No callback");
186 HILOGE("[IcSdkImpl]AieClientRelease failed. Error code[%d]", retCode);
187 return IC_RETCODE_FAILURE;
188 }
189 retCode = AieClientDestroy(clientInfo_);
190 icHandle_ = INVALID_IC_HANDLE;
191 if (retCode != RETCODE_SUCCESS) {
192 (callback_ != nullptr) ? (callback_->OnError(IC_RETCODE_FAILURE))
193 : HILOGD("[IcSdkImpl]No callback");
194 HILOGE("[IcSdkImpl]AieClientDestroy failed. Error code[%d]", retCode);
195 return IC_RETCODE_FAILURE;
196 }
197 return IC_RETCODE_SUCCESS;
198 }