• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "avmetadatahelper_server.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "engine_factory_repo.h"
20 #include "uri_helper.h"
21 #include "media_dfx.h"
22 #include "media_utils.h"
23 #include "ipc_skeleton.h"
24 
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_METADATA, "AVMetadataHelperServer"};
27 }
28 
29 namespace OHOS {
30 namespace Media {
31 static const std::unordered_map<int32_t, std::string> STATUS_TO_STATUS_DESCRIPTION_TABLE = {
32     {HELPER_STATE_ERROR, "HELPER_STATE_ERROR"},
33     {HELPER_IDLE, "HELPER_IDLE"},
34     {HELPER_PREPARED, "HELPER_PREPARED"},
35     {HELPER_CALL_DONE, "HELPER_CALL_DONE"},
36     {HELPER_RELEASED, "HELPER_RELEASED"},
37 };
38 
Create()39 std::shared_ptr<IAVMetadataHelperService> AVMetadataHelperServer::Create()
40 {
41     std::shared_ptr<AVMetadataHelperServer> server = std::make_shared<AVMetadataHelperServer>();
42     CHECK_AND_RETURN_RET_LOG(server != nullptr, nullptr, "Failed to new AVMetadataHelperServer");
43     return server;
44 }
45 
AVMetadataHelperServer()46 AVMetadataHelperServer::AVMetadataHelperServer()
47     : taskQue_("AVMetadata")
48 {
49     appUid_ = IPCSkeleton::GetCallingUid();
50     appPid_ = IPCSkeleton::GetCallingPid();
51     appName_ = GetClientBundleName(appUid_);
52     appTokenId_ = IPCSkeleton::GetCallingTokenID();
53     MEDIA_LOGI("appUid: %{public}d, appPid: %{public}d, appName: %{public}s", appUid_, appPid_, appName_.c_str());
54     (void)taskQue_.Start();
55     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
56 }
57 
~AVMetadataHelperServer()58 AVMetadataHelperServer::~AVMetadataHelperServer()
59 {
60     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
61     std::lock_guard<std::mutex> lock(mutex_);
62     auto task = std::make_shared<TaskHandler<void>>([&, this] {
63         avMetadataHelperEngine_ = nullptr;
64         uriHelper_ = nullptr;
65     });
66     (void)taskQue_.EnqueueTask(task, true);
67     (void)task->GetResult();
68     taskQue_.Stop();
69 }
70 
SetSource(const std::string & uri,int32_t usage)71 int32_t AVMetadataHelperServer::SetSource(const std::string &uri, int32_t usage)
72 {
73     std::unique_lock<std::mutex> lock(mutex_);
74     MediaTrace trace("AVMetadataHelperServer::SetSource_uri");
75     MEDIA_LOGD("Current uri is : %{private}s %{public}u", uri.c_str(), usage);
76     CHECK_AND_RETURN_RET_LOG(!uri.empty(), MSERR_INVALID_VAL, "uri is empty");
77     int32_t setSourceRes = MSERR_OK;
78     std::atomic<bool> isInitEngineEnd = false;
79 
80     auto task = std::make_shared<TaskHandler<int32_t>>([this, usage, uri, &isInitEngineEnd, &setSourceRes] {
81         MediaTrace trace("AVMetadataHelperServer::SetSource_uri_task");
82         {
83             std::unique_lock<std::mutex> lock(mutex_);
84             uriHelper_ = std::make_unique<UriHelper>(uri);
85             int32_t res = CheckSourceByUriHelper();
86             isInitEngineEnd = true;
87             if (res != MSERR_OK) {
88                 setSourceRes = res;
89                 ipcReturnCond_.notify_all();
90                 return res;
91             }
92             ipcReturnCond_.notify_all();
93         }
94         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr,
95             static_cast<int32_t>(MSERR_CREATE_AVMETADATAHELPER_ENGINE_FAILED),
96             "Failed to create avmetadatahelper engine");
97         int32_t ret = avMetadataHelperEngine_->SetSource(uriHelper_->FormattedUri(), usage);
98         currState_ = ret == MSERR_OK ? HELPER_PREPARED : HELPER_STATE_ERROR;
99         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "0x%{public}06" PRIXPTR " SetSource failed", FAKE_POINTER(this));
100         return ret;
101     });
102     CHECK_AND_RETURN_RET_LOG(task != nullptr, MSERR_NO_MEMORY, "Failed to create task");
103     taskQue_.EnqueueTask(task);
104     ipcReturnCond_.wait(lock, [this, &isInitEngineEnd] {
105         return isInitEngineEnd.load() || isInterrupted_.load();
106     });
107     CHECK_AND_RETURN_RET_LOG(isInterrupted_.load() == false, MSERR_INVALID_OPERATION, "SetSource interrupted");
108     return setSourceRes;
109 }
110 
SetAVMetadataCaller(AVMetadataCaller caller)111 int32_t AVMetadataHelperServer::SetAVMetadataCaller(AVMetadataCaller caller)
112 {
113     MediaTrace trace("AVMetadataHelperServer::SetAVMetadataCaller");
114     std::unique_lock<std::mutex> lock(mutex_);
115     CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, static_cast<int32_t>(MSERR_INVALID_OPERATION),
116         "avMetadataHelperEngine_ is nullptr");
117     return avMetadataHelperEngine_->SetAVMetadataCaller(caller);
118 }
119 
SetUrlSource(const std::string & uri,const std::map<std::string,std::string> & header)120 int32_t AVMetadataHelperServer::SetUrlSource(const std::string &uri, const std::map<std::string, std::string> &header)
121 {
122     MediaTrace trace("AVMetadataHelperServer::SetUrlSource");
123     std::unique_lock<std::mutex> lock(mutex_);
124     MEDIA_LOGD("Current uri is : %{private}s", uri.c_str());
125     CHECK_AND_RETURN_RET_LOG(!uri.empty(), MSERR_INVALID_VAL, "uri is empty");
126     int32_t setSourceRes = MSERR_OK;
127     std::atomic<bool> isInitEngineEnd = false;
128 
129     auto task = std::make_shared<TaskHandler<int32_t>>([this, header, uri, &isInitEngineEnd, &setSourceRes] {
130         MediaTrace trace("AVMetadataHelperServer::SetUrlSource_task");
131         {
132             std::unique_lock<std::mutex> lock(mutex_);
133             int32_t res = InitEngine(uri);
134             isInitEngineEnd = true;
135             if (res != MSERR_OK) {
136                 setSourceRes = res;
137                 ipcReturnCond_.notify_all();
138                 return res;
139             }
140             ipcReturnCond_.notify_all();
141         }
142         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr,
143             static_cast<int32_t>(MSERR_CREATE_AVMETADATAHELPER_ENGINE_FAILED),
144             "Failed to create avmetadatahelper engine");
145         int32_t ret = avMetadataHelperEngine_->SetUrlSource(uri, header);
146         currState_ = ret == MSERR_OK ? HELPER_PREPARED : HELPER_STATE_ERROR;
147         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "0x%{public}06" PRIXPTR " SetUrlSource failed",
148             FAKE_POINTER(this));
149         return ret;
150     });
151     CHECK_AND_RETURN_RET_LOG(task != nullptr, MSERR_NO_MEMORY, "Failed to create task");
152     taskQue_.EnqueueTask(task);
153     ipcReturnCond_.wait(lock, [this, &isInitEngineEnd] {
154         return isInitEngineEnd.load() || isInterrupted_.load();
155     });
156     CHECK_AND_RETURN_RET_LOG(isInterrupted_.load() == false, MSERR_INVALID_OPERATION, "SetUrlSource interrupted");
157     return setSourceRes;
158 }
159 
CheckSourceByUriHelper()160 int32_t AVMetadataHelperServer::CheckSourceByUriHelper()
161 {
162     CHECK_AND_RETURN_RET_LOG(uriHelper_ != nullptr, MSERR_NO_MEMORY, "Failed to create UriHelper");
163     CHECK_AND_RETURN_RET_LOG(!uriHelper_->FormattedUri().empty(),
164                              MSERR_INVALID_VAL,
165                              "Failed to construct formatted uri");
166     CHECK_AND_RETURN_RET_LOG(uriHelper_->AccessCheck(UriHelper::URI_READ),
167                              MSERR_INVALID_VAL,
168                              "Failed to read the file");
169     return InitEngine(uriHelper_->FormattedUri());
170 }
171 
SetSource(int32_t fd,int64_t offset,int64_t size,int32_t usage)172 int32_t AVMetadataHelperServer::SetSource(int32_t fd, int64_t offset, int64_t size, int32_t usage)
173 {
174     std::unique_lock<std::mutex> lock(mutex_);
175     MediaTrace trace("AVMetadataHelperServer::SetSource_fd");
176     MEDIA_LOGD("Current is fd source, offset: %{public}" PRIi64 ", size: %{public}" PRIi64 " usage: %{public}u",
177                offset, size, usage);
178     int32_t setSourceRes = MSERR_OK;
179     std::atomic<bool> isInitEngineEnd = false;
180 
181     auto task = std::make_shared<TaskHandler<int32_t>>([this, fd, offset, size,
182                                                         usage, &isInitEngineEnd, &setSourceRes] {
183         MediaTrace trace("AVMetadataHelperServer::SetSource_fd_task");
184         {
185             std::unique_lock<std::mutex> lock(mutex_);
186             uriHelper_ = std::make_unique<UriHelper>(fd, offset, size);
187             int32_t res = CheckSourceByUriHelper();
188             isInitEngineEnd = true;
189             if (res != MSERR_OK) {
190                 setSourceRes = res;
191                 ipcReturnCond_.notify_all();
192                 return res;
193             }
194             ipcReturnCond_.notify_all();
195         }
196         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr,
197             static_cast<int32_t>(MSERR_CREATE_AVMETADATAHELPER_ENGINE_FAILED),
198             "Failed to create avmetadatahelper engine");
199 
200         int32_t ret = avMetadataHelperEngine_->SetSource(uriHelper_->FormattedUri(), usage);
201         currState_ = ret == MSERR_OK ? HELPER_PREPARED : HELPER_STATE_ERROR;
202         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "0x%{public}06" PRIXPTR " SetSource failed", FAKE_POINTER(this));
203         return ret;
204     });
205     CHECK_AND_RETURN_RET_LOG(task != nullptr, MSERR_NO_MEMORY, "Failed to create task");
206     taskQue_.EnqueueTask(task);
207     ipcReturnCond_.wait(lock, [this, &isInitEngineEnd] {
208         return isInitEngineEnd.load() || isInterrupted_.load();
209     });
210     CHECK_AND_RETURN_RET_LOG(isInterrupted_.load() == false, MSERR_INVALID_OPERATION, "SetSource interrupted");
211     return setSourceRes;
212 }
213 
SetSource(const std::shared_ptr<IMediaDataSource> & dataSrc)214 int32_t AVMetadataHelperServer::SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)
215 {
216     std::unique_lock<std::mutex> lock(mutex_);
217     MediaTrace trace("AVMetadataHelperServer::SetSource dataSrc");
218     MEDIA_LOGD("AVMetadataHelperServer SetSource");
219     CHECK_AND_RETURN_RET_LOG(dataSrc != nullptr, MSERR_INVALID_VAL, "data source is nullptr");
220     dataSrc_ = dataSrc;
221     int32_t setSourceRes = MSERR_OK;
222     std::atomic<bool> isInitEngineEnd = false;
223 
224     auto task = std::make_shared<TaskHandler<int32_t>>([this, dataSrc, &isInitEngineEnd, &setSourceRes] {
225         MediaTrace trace("AVMetadataHelperServer::SetSource dataSrc_task");
226         {
227             std::unique_lock<std::mutex> lock(mutex_);
228             int32_t res = InitEngine("media data source");
229             isInitEngineEnd = true;
230             if (res != MSERR_OK) {
231                 setSourceRes = res;
232                 ipcReturnCond_.notify_all();
233                 return res;
234             }
235             ipcReturnCond_.notify_all();
236         }
237         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr,
238             static_cast<int32_t>(MSERR_CREATE_AVMETADATAHELPER_ENGINE_FAILED),
239             "Failed to create avmetadatahelper engine");
240         int32_t ret = avMetadataHelperEngine_->SetSource(dataSrc);
241         currState_ = ret == MSERR_OK ? HELPER_PREPARED : HELPER_STATE_ERROR;
242         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "SetSource failed!");
243 
244         int64_t size = 0;
245         (void)dataSrc->GetSize(size);
246         if (size == -1) {
247             config_.looping = false;
248             isLiveStream_ = true;
249         }
250         return ret;
251     });
252     CHECK_AND_RETURN_RET_LOG(task != nullptr, MSERR_NO_MEMORY, "Failed to create task");
253     taskQue_.EnqueueTask(task);
254     ipcReturnCond_.wait(lock, [this, &isInitEngineEnd] {
255         return isInitEngineEnd.load() || isInterrupted_.load();
256     });
257     CHECK_AND_RETURN_RET_LOG(isInterrupted_.load() == false, MSERR_INVALID_OPERATION, "SetSource interrupted");
258     return setSourceRes;
259 }
260 
InitEngine(const std::string & uri)261 int32_t AVMetadataHelperServer::InitEngine(const std::string &uri)
262 {
263     auto engineFactory = EngineFactoryRepo::Instance().GetEngineFactory(
264         IEngineFactory::Scene::SCENE_AVMETADATA, appUid_, uri);
265     CHECK_AND_RETURN_RET_LOG(engineFactory != nullptr,
266         static_cast<int32_t>(MSERR_CREATE_AVMETADATAHELPER_ENGINE_FAILED),
267         "Failed to get engine factory");
268     avMetadataHelperEngine_ = engineFactory->CreateAVMetadataHelperEngine(appUid_, appPid_, appTokenId_, appName_);
269     CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr,
270         static_cast<int32_t>(MSERR_CREATE_AVMETADATAHELPER_ENGINE_FAILED),
271         "Failed to create avmetadatahelper engine");
272     return MSERR_OK;
273 }
274 
ResolveMetadata(int32_t key)275 std::string AVMetadataHelperServer::ResolveMetadata(int32_t key)
276 {
277     std::unique_lock<std::mutex> lock(mutex_);
278     MediaTrace trace("AVMetadataHelperServer::ResolveMetadata_key");
279     MEDIA_LOGD("Key is %{public}d", key);
280     auto task = std::make_shared<TaskHandler<std::string>>([this, key] {
281         MediaTrace trace("AVMetadataHelperServer::ResolveMetadata_key_task");
282         std::string err = "";
283         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, err, "avMetadataHelperEngine_ is nullptr");
284         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
285         return avMetadataHelperEngine_->ResolveMetadata(key);
286     });
287     int32_t ret = taskQue_.EnqueueTask(task);
288     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, "", "EnqueueTask failed");
289 
290     auto result = task->GetResult();
291     CHECK_AND_RETURN_RET_LOG(result.HasResult(), "", "task has been cleared");
292     ChangeState(HelperStates::HELPER_CALL_DONE);
293     return result.Value();
294 }
295 
ResolveMetadata()296 std::unordered_map<int32_t, std::string> AVMetadataHelperServer::ResolveMetadata()
297 {
298     std::unique_lock<std::mutex> lock(mutex_);
299     MediaTrace trace("AVMetadataHelperServer::ResolveMetadata");
300     auto task = std::make_shared<TaskHandler<std::unordered_map<int32_t, std::string>>>([this] {
301         MediaTrace trace("AVMetadataHelperServer::ResolveMetadata_task");
302         std::unordered_map<int32_t, std::string> err;
303         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, err, "avMetadataHelperEngine_ is nullptr");
304         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
305         return avMetadataHelperEngine_->ResolveMetadata();
306     });
307     int32_t ret = taskQue_.EnqueueTask(task);
308     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, {}, "EnqueueTask failed");
309 
310     auto result = task->GetResult();
311     CHECK_AND_RETURN_RET_LOG(result.HasResult(), {}, "task has been cleared");
312     ChangeState(HelperStates::HELPER_CALL_DONE);
313     return result.Value();
314 }
315 
GetAVMetadata()316 std::shared_ptr<Meta> AVMetadataHelperServer::GetAVMetadata()
317 {
318     std::unique_lock<std::mutex> lock(mutex_);
319     MediaTrace trace("AVMetadataHelperServer::ResolveMetadata");
320     auto task = std::make_shared<TaskHandler<std::shared_ptr<Meta>>>([this] {
321         MediaTrace trace("AVMetadataHelperServer::ResolveMetadata_task");
322         std::shared_ptr<Meta> err = nullptr;
323         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, err, "avMetadataHelperEngine_ is nullptr");
324         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
325         return avMetadataHelperEngine_->GetAVMetadata();
326     });
327     int32_t ret = taskQue_.EnqueueTask(task);
328     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, {}, "EnqueueTask failed");
329 
330     auto result = task->GetResult();
331     CHECK_AND_RETURN_RET_LOG(result.HasResult(), {}, "task has been cleared");
332     ChangeState(HelperStates::HELPER_CALL_DONE);
333     return result.Value();
334 }
335 
FetchArtPicture()336 std::shared_ptr<AVSharedMemory> AVMetadataHelperServer::FetchArtPicture()
337 {
338     std::unique_lock<std::mutex> lock(mutex_);
339     MediaTrace trace("AVMetadataHelperServer::FetchArtPicture");
340     auto task = std::make_shared<TaskHandler<std::shared_ptr<AVSharedMemory>>>([this] {
341         MediaTrace trace("AVMetadataHelperServer::FetchArtPicture_task");
342         std::shared_ptr<AVSharedMemory> err = nullptr;
343         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, err, "avMetadataHelperEngine_ is nullptr");
344         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
345         return avMetadataHelperEngine_->FetchArtPicture();
346     });
347     int32_t ret = taskQue_.EnqueueTask(task);
348     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "EnqueueTask failed");
349 
350     auto result = task->GetResult();
351     CHECK_AND_RETURN_RET_LOG(result.HasResult(), nullptr, "task has been cleared");
352     if (result.Value() == nullptr) {
353         MEDIA_LOGE("FetchArtPicture result is nullptr.");
354         NotifyErrorCallback(HelperErrorType::INVALID_RESULT, "FetchArtPicture result is nullptr.");
355         return nullptr;
356     }
357     ChangeState(HelperStates::HELPER_CALL_DONE);
358     return result.Value();
359 }
360 
FetchFrameAtTime(int64_t timeUs,int32_t option,const OutputConfiguration & param)361 std::shared_ptr<AVSharedMemory> AVMetadataHelperServer::FetchFrameAtTime(int64_t timeUs, int32_t option,
362     const OutputConfiguration &param)
363 {
364     std::unique_lock<std::mutex> lock(mutex_);
365     MediaTrace trace("AVMetadataHelperServer::FetchFrameAtTime");
366     auto task = std::make_shared<TaskHandler<std::shared_ptr<AVSharedMemory>>>([this, timeUs, option, param] {
367         MediaTrace trace("AVMetadataHelperServer::FetchFrameAtTime_task");
368         std::shared_ptr<AVSharedMemory> err = nullptr;
369         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, err, "avMetadataHelperEngine_ is nullptr");
370         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
371         return avMetadataHelperEngine_->FetchFrameAtTime(timeUs, option, param);
372     });
373     int32_t ret = taskQue_.EnqueueTask(task);
374     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "EnqueueTask failed");
375 
376     auto result = task->GetResult();
377     CHECK_AND_RETURN_RET_LOG(result.HasResult(), nullptr, "task has been cleared");
378     ChangeState(HelperStates::HELPER_CALL_DONE);
379     return result.Value();
380 }
381 
FetchFrameYuv(int64_t timeUs,int32_t option,const OutputConfiguration & param)382 std::shared_ptr<AVBuffer> AVMetadataHelperServer::FetchFrameYuv(int64_t timeUs, int32_t option,
383     const OutputConfiguration &param)
384 {
385     MediaTrace trace("AVMetadataHelperServer::FetchFrameAtTime");
386     std::unique_lock<std::mutex> lock(mutex_);
387     auto task = std::make_shared<TaskHandler<std::shared_ptr<AVBuffer>>>([this, timeUs, option, param] {
388         MediaTrace trace("AVMetadataHelperServer::FetchFrameAtTime_task");
389         std::shared_ptr<AVBuffer> err = nullptr;
390         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, err, "avMetadataHelperEngine_ is nullptr");
391         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
392         return avMetadataHelperEngine_->FetchFrameYuv(timeUs, option, param);
393     });
394     int32_t ret = taskQue_.EnqueueTask(task);
395     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "EnqueueTask failed");
396     auto result = task->GetResult();
397     CHECK_AND_RETURN_RET_LOG(result.HasResult(), nullptr, "task has been cleared");
398     return result.Value();
399 }
400 
Release()401 void AVMetadataHelperServer::Release()
402 {
403     MediaTrace trace("AVMetadataHelperServer::Release");
404     {
405         auto avMetadataHelperEngine = avMetadataHelperEngine_;
406         CHECK_AND_RETURN_LOG(avMetadataHelperEngine != nullptr, "avMetadataHelperEngine_ is nullptr");
407         avMetadataHelperEngine->SetInterruptState(true);
408     }
409 
410     auto task = std::make_shared<TaskHandler<void>>([&, this] {
411         avMetadataHelperEngine_ = nullptr;
412         uriHelper_ = nullptr;
413         ChangeState(HelperStates::HELPER_RELEASED);
414         {
415             std::lock_guard<std::mutex> lockCb(mutexCb_);
416             helperCb_ = nullptr;
417         }
418     });
419     (void)taskQue_.EnqueueTask(task, true);
420     (void)task->GetResult();
421     std::unique_lock<std::mutex> lock(mutex_);
422     isInterrupted_ = true;
423     ipcReturnCond_.notify_all();
424 }
425 
SetHelperCallback(const std::shared_ptr<HelperCallback> & callback)426 int32_t AVMetadataHelperServer::SetHelperCallback(const std::shared_ptr<HelperCallback> &callback)
427 {
428     std::lock_guard<std::mutex> lock(mutex_);
429     CHECK_AND_RETURN_RET_LOG(callback != nullptr, MSERR_INVALID_VAL, "callback is nullptr");
430 
431     if (currState_ != HELPER_IDLE) {
432         MEDIA_LOGE("Can not SetHelperCallback, currentState is %{public}s",
433             GetStatusDescription(currState_).c_str());
434         return MSERR_INVALID_OPERATION;
435     }
436 
437     {
438         std::lock_guard<std::mutex> lockCb(mutexCb_);
439         helperCb_ = callback;
440     }
441     return MSERR_OK;
442 }
443 
GetTimeByFrameIndex(uint32_t index,uint64_t & time)444 int32_t AVMetadataHelperServer::GetTimeByFrameIndex(uint32_t index, uint64_t &time)
445 {
446     MediaTrace trace("AVMetadataHelperServer::GetTimeByFrameIndex");
447     std::unique_lock<std::mutex> lock(mutex_);
448     auto task = std::make_shared<TaskHandler<int32_t>>([this, &timeUs = time, index] {
449         MediaTrace trace("AVMetadataHelperServer::GetTimeByFrameIndex_task");
450         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, static_cast<int32_t>(MSERR_NO_MEMORY),
451                                  "avMetadataHelperEngine_ is nullptr");
452         int32_t err = static_cast<int32_t>(MSERR_INVALID_STATE);
453         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
454         return avMetadataHelperEngine_->GetTimeByFrameIndex(index, timeUs);
455     });
456     int32_t ret = taskQue_.EnqueueTask(task);
457     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_NO_MEMORY, "EnqueueTask failed");
458     auto result = task->GetResult();
459     CHECK_AND_RETURN_RET_LOG(result.HasResult(), MSERR_INVALID_STATE, "task has been cleared");
460     return result.Value();
461 }
462 
GetFrameIndexByTime(uint64_t time,uint32_t & index)463 int32_t AVMetadataHelperServer::GetFrameIndexByTime(uint64_t time, uint32_t &index)
464 {
465     MediaTrace trace("AVMetadataHelperServer::GetFrameIndexByTime");
466     std::unique_lock<std::mutex> lock(mutex_);
467     auto task = std::make_shared<TaskHandler<int32_t>>([this, &index = index, time] {
468         MediaTrace trace("AVMetadataHelperServer::GetFrameIndexByTime_task");
469         CHECK_AND_RETURN_RET_LOG(avMetadataHelperEngine_ != nullptr, static_cast<int32_t>(MSERR_NO_MEMORY),
470                                  "avMetadataHelperEngine_ is nullptr");
471         int32_t err = static_cast<int32_t>(MSERR_INVALID_STATE);
472         CHECK_AND_RETURN_RET(currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE, err);
473         return avMetadataHelperEngine_->GetFrameIndexByTime(time, index);
474     });
475     int32_t ret = taskQue_.EnqueueTask(task);
476     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
477     auto result = task->GetResult();
478     CHECK_AND_RETURN_RET_LOG(result.HasResult(), MSERR_INVALID_STATE, "task has been cleared");
479     return result.Value();
480 }
481 
ChangeState(const HelperStates state)482 void AVMetadataHelperServer::ChangeState(const HelperStates state)
483 {
484     switch (state) {
485         case HELPER_PREPARED:
486             if (currState_ == HELPER_IDLE) {
487                 currState_ = HELPER_PREPARED;
488                 NotifyInfoCallback(HELPER_INFO_TYPE_STATE_CHANGE, currState_);
489             } else {
490                 NotifyErrorCallback(HelperErrorType::INVALID_OPERATION, "State error, current Operation is invalid.");
491             }
492             break;
493         case HELPER_CALL_DONE:
494             if (currState_ == HELPER_CALL_DONE || currState_ == HELPER_PREPARED) {
495                 currState_ = HELPER_CALL_DONE;
496                 NotifyInfoCallback(HELPER_INFO_TYPE_STATE_CHANGE, currState_);
497             } else {
498                 NotifyErrorCallback(HelperErrorType::INVALID_OPERATION, "State error, current Operation is invalid.");
499             }
500             break;
501         case HELPER_RELEASED:
502             if (currState_ == HELPER_IDLE || currState_ == HELPER_PREPARED || currState_ == HELPER_CALL_DONE) {
503                 currState_ = HELPER_RELEASED;
504                 NotifyInfoCallback(HELPER_INFO_TYPE_STATE_CHANGE, currState_);
505             } else {
506                 NotifyErrorCallback(HelperErrorType::INVALID_OPERATION, "State error, current Operation is invalid.");
507             }
508             break;
509         case HELPER_STATE_ERROR:
510             currState_ = HELPER_STATE_ERROR;
511             NotifyInfoCallback(HELPER_INFO_TYPE_STATE_CHANGE, currState_);
512             break;
513         default:
514             MEDIA_LOGI("Changed state is invalid.");
515             break;
516     }
517 }
518 
NotifyErrorCallback(int32_t code,const std::string msg)519 void AVMetadataHelperServer::NotifyErrorCallback(int32_t code, const std::string msg)
520 {
521     std::lock_guard<std::mutex> lockCb(mutexCb_);
522     MEDIA_LOGD("NotifyErrorCallback error code: %{public}d", code);
523     if (helperCb_ != nullptr) {
524         helperCb_->OnError(code, msg);
525     }
526 }
527 
NotifyInfoCallback(HelperOnInfoType type,int32_t extra)528 void AVMetadataHelperServer::NotifyInfoCallback(HelperOnInfoType type, int32_t extra)
529 {
530     std::lock_guard<std::mutex> lockCb(mutexCb_);
531     MEDIA_LOGD("NotifyInfoCallback, extra: %{public}d", extra);
532     if (helperCb_ != nullptr) {
533         helperCb_->OnInfo(type, extra);
534     }
535 }
536 
GetStatusDescription(int32_t status)537 const std::string &AVMetadataHelperServer::GetStatusDescription(int32_t status)
538 {
539     static const std::string ILLEGAL_STATE = "PLAYER_STATUS_ILLEGAL";
540     if (status < HELPER_STATE_ERROR || status > HELPER_RELEASED) {
541         return ILLEGAL_STATE;
542     }
543 
544     return STATUS_TO_STATUS_DESCRIPTION_TABLE.find(status)->second;
545 }
546 } // namespace Media
547 } // namespace OHOS
548