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 ¶m)
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 ¶m)
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