• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "video_processing_client.h"
17 
18 #include "iservice_registry.h"
19 #include "video_processing_load_callback.h"
20 #include "vpe_sa_constants.h"
21 
22 using namespace OHOS::Media::VideoProcessingEngine;
23 using namespace OHOS;
24 using namespace std::chrono_literals;
25 using namespace std::placeholders;
26 
27 using VpeSa = IVideoProcessingServiceManager;
28 
29 namespace {
30 std::mutex g_proxyLock;
31 constexpr int ERROR_DEAD_REPLY = 29189;
32 constexpr int DEAD_RETRY_COUNT = 5;
33 }
34 
GetInstance()35 VideoProcessingManager& VideoProcessingManager::GetInstance()
36 {
37     static VideoProcessingManager instance;
38     return instance;
39 }
40 
Connect()41 void VideoProcessingManager::Connect()
42 {
43     VPE_LOGD("call GetService");
44     GetService();
45 }
46 
Disconnect()47 void VideoProcessingManager::Disconnect()
48 {
49     VPE_LOGD("VideoProcessingManager Disconnect!");
50     return;
51 }
52 
LoadInfo(int32_t key,SurfaceBufferInfo & bufferInfo)53 ErrCode VideoProcessingManager::LoadInfo(int32_t key, SurfaceBufferInfo& bufferInfo)
54 {
55     std::lock_guard<std::mutex> lock(g_proxyLock);
56     return Execute([&key, &bufferInfo](sptr<VpeSa>& proxy) { return proxy->LoadInfo(key, bufferInfo); }, VPE_LOG_INFO);
57 }
58 
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)59 void VideoProcessingManager::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
60 {
61     VPE_LOGI("Get VideoProcessingService SA success!");
62     std::unique_lock<std::mutex> lock(g_proxyLock);
63     if (remoteObject != nullptr) {
64         VPE_LOGD("remoteObject is not null.");
65         proxy_ = iface_cast<IVideoProcessingServiceManager>(remoteObject);
66         cvProxy_.notify_one();
67     }
68 }
69 
LoadSystemAbilityFail()70 void VideoProcessingManager::LoadSystemAbilityFail()
71 {
72     VPE_LOGE("Get VideoProcessingService SA failed!");
73     std::unique_lock<std::mutex> lock(g_proxyLock);
74     proxy_ = nullptr;
75 }
76 
Create(const std::string & feature,const std::string & clientName,uint32_t & clientID)77 VPEAlgoErrCode VideoProcessingManager::Create(const std::string& feature, const std::string& clientName,
78     uint32_t& clientID)
79 {
80     int id;
81     auto ret = Execute(std::bind(&VpeSa::Create, _1, feature, clientName, std::ref(id)), VPE_LOG_INFO);
82     if (ret == ERR_NONE) {
83         clientID = static_cast<uint32_t>(id);
84         VPE_LOGD("feature:%{public}s client:%{public}s -> ID:%{public}d", feature.c_str(), clientName.c_str(), id);
85     } else {
86         VPE_LOGE("feature:%{public}s client:%{public}s failed! ret:%{public}d", feature.c_str(), clientName.c_str(),
87             ret);
88     }
89     return ret;
90 }
91 
Destroy(uint32_t clientID)92 VPEAlgoErrCode VideoProcessingManager::Destroy(uint32_t clientID)
93 {
94     return Execute(std::bind(&VpeSa::Destroy, _1, clientID), VPE_LOG_INFO);
95 }
96 
SetParameter(uint32_t clientID,int32_t tag,const std::vector<uint8_t> & parameter)97 VPEAlgoErrCode VideoProcessingManager::SetParameter(uint32_t clientID, int32_t tag,
98     const std::vector<uint8_t>& parameter)
99 {
100     return Execute(std::bind(&VpeSa::SetParameter, _1, clientID, tag, parameter), VPE_LOG_INFO);
101 }
102 
SetParameter(uint32_t clientID,int32_t tag)103 VPEAlgoErrCode VideoProcessingManager::SetParameter(uint32_t clientID, int32_t tag)
104 {
105     std::vector<uint8_t> param;
106     return SetParameter(clientID, tag, param);
107 }
108 
GetParameter(uint32_t clientID,int32_t tag,std::vector<uint8_t> & parameter)109 VPEAlgoErrCode VideoProcessingManager::GetParameter(uint32_t clientID, int32_t tag, std::vector<uint8_t>& parameter)
110 {
111     return Execute(std::bind(&VpeSa::GetParameter, _1, clientID, tag, parameter), VPE_LOG_INFO);
112 }
113 
UpdateMetadata(uint32_t clientID,SurfaceBufferInfo & image)114 VPEAlgoErrCode VideoProcessingManager::UpdateMetadata(uint32_t clientID, SurfaceBufferInfo& image)
115 {
116     return Execute(std::bind(&VpeSa::UpdateMetadata, _1, clientID, image), VPE_LOG_INFO);
117 }
118 
Process(uint32_t clientID,const SurfaceBufferInfo & input,SurfaceBufferInfo & output)119 VPEAlgoErrCode VideoProcessingManager::Process(uint32_t clientID, const SurfaceBufferInfo& input,
120     SurfaceBufferInfo& output)
121 {
122     return Execute(std::bind(&VpeSa::Process, _1, clientID, input, output), VPE_LOG_INFO);
123 }
124 
ComposeImage(uint32_t clientID,const SurfaceBufferInfo & inputSdrImage,const SurfaceBufferInfo & inputGainmap,SurfaceBufferInfo & outputHdrImage,bool legacy)125 VPEAlgoErrCode VideoProcessingManager::ComposeImage(uint32_t clientID, const SurfaceBufferInfo& inputSdrImage,
126     const SurfaceBufferInfo& inputGainmap, SurfaceBufferInfo& outputHdrImage, bool legacy)
127 {
128     return Execute(std::bind(&VpeSa::ComposeImage, _1, clientID, inputSdrImage, inputGainmap, outputHdrImage, legacy),
129         VPE_LOG_INFO);
130 }
131 
DecomposeImage(uint32_t clientID,const SurfaceBufferInfo & inputImage,SurfaceBufferInfo & outputSdrImage,SurfaceBufferInfo & outputGainmap)132 VPEAlgoErrCode VideoProcessingManager::DecomposeImage(uint32_t clientID, const SurfaceBufferInfo& inputImage,
133     SurfaceBufferInfo& outputSdrImage, SurfaceBufferInfo& outputGainmap)
134 {
135     return Execute(std::bind(&VpeSa::DecomposeImage, _1, clientID, inputImage, outputSdrImage, outputGainmap),
136         VPE_LOG_INFO);
137 }
138 
GetService()139 sptr<IVideoProcessingServiceManager> VideoProcessingManager::GetService()
140 {
141     do {
142         std::lock_guard<std::mutex> lock(lock_);
143         if (proxy_ != nullptr) {
144             if (proxy_->AsObject() != nullptr && !proxy_->AsObject()->IsObjectDead()) [[likely]] {
145                 return proxy_;
146             }
147             VPE_LOGD("SA remote died.");
148             ClearSaLocked();
149         }
150 
151         if (isLoading_.load()) {
152             VPE_LOGD("SA is loading, so wait for the result directly .");
153             break;
154         }
155 
156         auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
157         CHECK_AND_RETURN_RET_LOG(samgr != nullptr, nullptr, "Failed to GetSystemAbilityManager!");
158         VPE_LOGD("Try to check VPE SA.");
159         auto object = samgr->CheckSystemAbility(VIDEO_PROCESSING_SERVER_SA_ID);
160         if (object != nullptr) {
161             proxy_ = iface_cast<IVideoProcessingServiceManager>(object);
162             VPE_LOGD("SA is already start");
163             return proxy_;
164         }
165 
166         sptr<LoadCallback> loadCallback = new(std::nothrow) LoadCallback(
167             std::bind(&VideoProcessingManager::OnSaLoad, this, _1),
168             std::bind(&VideoProcessingManager::OnSaLoad, this, nullptr));
169         CHECK_AND_RETURN_RET_LOG(loadCallback != nullptr, nullptr, "Failed to create LoadCallback!");
170         VPE_LOGD("Loading VPE SA...");
171         CHECK_AND_RETURN_RET_LOG(samgr->LoadSystemAbility(VIDEO_PROCESSING_SERVER_SA_ID, loadCallback) == ERR_OK,
172             nullptr, "Failed to load VPE SA!");
173         isLoading_ = true;
174     } while (false);
175 
176     std::unique_lock lock(lock_);
177     CHECK_AND_RETURN_RET_LOG(cvProxy_.wait_for(lock, 1s, [this] { return !isLoading_.load(); }), nullptr,
178         "load SA timeout!");
179     if (proxy_ != nullptr) {
180         VPE_LOGD("Finish loading VPE SA success.");
181     } else {
182         VPE_LOGE("Finish loading VPE SA fail!");
183     }
184     return proxy_;
185 }
186 
OnSaLoad(const sptr<IRemoteObject> & remoteObject)187 void VideoProcessingManager::OnSaLoad(const sptr<IRemoteObject>& remoteObject)
188 {
189     {
190         std::lock_guard<std::mutex> lock(lock_);
191         if (remoteObject != nullptr) {
192             sptr<DeathObserver> observer = new(std::nothrow) DeathObserver(
193                 std::bind(&VideoProcessingManager::OnSaDied, this, _1));
194             CHECK_AND_RETURN_LOG(observer != nullptr, "Failed to create DeathObserver!");
195             CHECK_AND_RETURN_LOG(remoteObject->AddDeathRecipient(observer), "Failed to AddDeathRecipient!");
196             VPE_LOGD("AddDeathRecipient success.");
197             proxy_ = iface_cast<IVideoProcessingServiceManager>(remoteObject);
198             VPE_LOGI("SA load success.");
199         } else {
200             proxy_ = nullptr;
201             VPE_LOGE("SA load fail!");
202         }
203         isLoading_ = false;
204     }
205     cvProxy_.notify_all();
206 }
207 
OnSaDied(const wptr<IRemoteObject> & remoteObject)208 void VideoProcessingManager::OnSaDied([[maybe_unused]] const wptr<IRemoteObject>& remoteObject)
209 {
210     std::lock_guard<std::mutex> lock(lock_);
211     proxy_ = nullptr;
212 }
213 
Execute(std::function<ErrCode (sptr<IVideoProcessingServiceManager> &)> && operation,const LogInfo & logInfo)214 VPEAlgoErrCode VideoProcessingManager::Execute(
215     std::function<ErrCode(sptr<IVideoProcessingServiceManager>&)>&& operation, const LogInfo& logInfo)
216 {
217     auto proxy = GetService();
218     if (proxy == nullptr) [[unlikely]] {
219         VPE_ORG_LOGE(logInfo, "proxy is null!");
220         return VPE_ALGO_ERR_INVALID_STATE;
221     }
222     auto err = static_cast<VPEAlgoErrCode>(operation(proxy));
223     if (err == ERROR_DEAD_REPLY) {
224         ClearSa();
225         if (deadRetryCount_.load() < DEAD_RETRY_COUNT) {
226             deadRetryCount_++;
227             VPE_ORG_LOGD(logInfo, "<%{public}d> Retry to check SA again for dead reply.", deadRetryCount_.load());
228             return Execute(std::move(operation), logInfo);
229         }
230     } else {
231         deadRetryCount_.store(0);
232     }
233     return err;
234 }
235 
ClearSa()236 void VideoProcessingManager::ClearSa()
237 {
238     std::lock_guard<std::mutex> lock(lock_);
239     ClearSaLocked();
240 }
241 
ClearSaLocked()242 void VideoProcessingManager::ClearSaLocked()
243 {
244     proxy_ = nullptr;
245     isLoading_ = false;
246 }
247 
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)248 void VideoProcessingManager::LoadCallback::OnLoadSystemAbilitySuccess([[maybe_unused]] int32_t systemAbilityId,
249     const sptr<IRemoteObject>& remoteObject)
250 {
251     onSuccess_(remoteObject);
252 }
253 
OnLoadSystemAbilityFail(int32_t systemAbilityId)254 void VideoProcessingManager::LoadCallback::OnLoadSystemAbilityFail([[maybe_unused]] int32_t systemAbilityId)
255 {
256     onFail_();
257 }
258 
OnRemoteDied(const wptr<IRemoteObject> & remoteObject)259 void VideoProcessingManager::DeathObserver::OnRemoteDied(const wptr<IRemoteObject>& remoteObject)
260 {
261     onRemoteDied_(remoteObject);
262 }