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 #include "transcoder_server.h"
17 #include "map"
18 #include "media_log.h"
19 #include "media_errors.h"
20 #include "engine_factory_repo.h"
21 #include "param_wrapper.h"
22 #include "accesstoken_kit.h"
23 #include "ipc_skeleton.h"
24 #include "media_dfx.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "TransCoderServer"};
28 const std::map<OHOS::Media::TransCoderServer::RecStatus, std::string> TRANSCODER_STATE_MAP = {
29 {OHOS::Media::TransCoderServer::REC_INITIALIZED, "initialized"},
30 {OHOS::Media::TransCoderServer::REC_CONFIGURED, "configured"},
31 {OHOS::Media::TransCoderServer::REC_PREPARED, "prepared"},
32 {OHOS::Media::TransCoderServer::REC_TRANSCODERING, "transcordring"},
33 {OHOS::Media::TransCoderServer::REC_PAUSED, "paused"},
34 {OHOS::Media::TransCoderServer::REC_ERROR, "error"},
35 };
36 }
37
38 namespace OHOS {
39 namespace Media {
40 const std::string START_TAG = "TransCoderCreate->Start";
41 const std::string STOP_TAG = "TransCoderStop->Destroy";
42
Create()43 std::shared_ptr<ITransCoderService> TransCoderServer::Create()
44 {
45 std::shared_ptr<TransCoderServer> server = std::make_shared<TransCoderServer>();
46 int32_t ret = server->Init();
47 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "failed to init TransCoderServer");
48 return server;
49 }
50
TransCoderServer()51 TransCoderServer::TransCoderServer()
52 : taskQue_("TranscoderServer")
53 {
54 taskQue_.Start();
55 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
56 instanceId_ = HiviewDFX::HiTraceChain::GetId().GetChainId();
57 }
58
~TransCoderServer()59 TransCoderServer::~TransCoderServer()
60 {
61 std::lock_guard<std::mutex> lock(mutex_);
62 ReleaseInner();
63 taskQue_.Stop();
64 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
65 }
66
Init()67 int32_t TransCoderServer::Init()
68 {
69 MediaTrace trace("TransCoderServer::Init");
70 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
71 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
72 int32_t appUid = IPCSkeleton::GetCallingUid();
73 int32_t appPid = IPCSkeleton::GetCallingPid();
74
75 auto task = std::make_shared<TaskHandler<MediaServiceErrCode>>([&, this] {
76 auto engineFactory = EngineFactoryRepo::Instance().GetEngineFactory(
77 IEngineFactory::Scene::SCENE_TRANSCODER, appUid);
78 CHECK_AND_RETURN_RET_LOG(engineFactory != nullptr, MSERR_CREATE_REC_ENGINE_FAILED,
79 "failed to get factory");
80 transCoderEngine_ = engineFactory->CreateTransCoderEngine(appUid, appPid, tokenId, fullTokenId);
81 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_CREATE_REC_ENGINE_FAILED,
82 "failed to create transCoder engine");
83 transCoderEngine_->SetInstanceId(instanceId_);
84 return MSERR_OK;
85 });
86 int32_t ret = taskQue_.EnqueueTask(task);
87 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
88
89 auto result = task->GetResult();
90 CHECK_AND_RETURN_RET_LOG(result.Value() == MSERR_OK, result.Value(), "Result failed");
91
92 status_ = REC_INITIALIZED;
93 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
94 return MSERR_OK;
95 }
96
GetStatusDescription(OHOS::Media::TransCoderServer::RecStatus status)97 const std::string& TransCoderServer::GetStatusDescription(OHOS::Media::TransCoderServer::RecStatus status)
98 {
99 static const std::string ILLEGAL_STATE = "PLAYER_STATUS_ILLEGAL";
100 CHECK_AND_RETURN_RET(status >= OHOS::Media::TransCoderServer::REC_INITIALIZED &&
101 status <= OHOS::Media::TransCoderServer::REC_ERROR, ILLEGAL_STATE);
102
103 return TRANSCODER_STATE_MAP.find(status)->second;
104 }
105
OnError(TransCoderErrorType errorType,int32_t errorCode)106 void TransCoderServer::OnError(TransCoderErrorType errorType, int32_t errorCode)
107 {
108 (void)errorType;
109 std::lock_guard<std::mutex> lock(cbMutex_);
110 lastErrMsg_ = MSErrorToExtErrorString(static_cast<MediaServiceErrCode>(errorCode));
111 FaultEventWrite(lastErrMsg_, "TransCoder");
112 CHECK_AND_RETURN(transCoderCb_ != nullptr);
113 transCoderCb_->OnError(errorCode, lastErrMsg_);
114 }
115
OnInfo(TransCoderOnInfoType type,int32_t extra)116 void TransCoderServer::OnInfo(TransCoderOnInfoType type, int32_t extra)
117 {
118 std::lock_guard<std::mutex> lock(cbMutex_);
119 CHECK_AND_RETURN(transCoderCb_ != nullptr);
120 transCoderCb_->OnInfo(type, extra);
121 }
122
SetVideoEncoder(VideoCodecFormat encoder)123 int32_t TransCoderServer::SetVideoEncoder(VideoCodecFormat encoder)
124 {
125 std::lock_guard<std::mutex> lock(mutex_);
126 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
127 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
128 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
129 config_.videoCodec = encoder;
130 VideoEnc vidEnc(encoder);
131 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
132 return transCoderEngine_->Configure(vidEnc);
133 });
134 int32_t ret = taskQue_.EnqueueTask(task);
135 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
136
137 auto result = task->GetResult();
138 return result.Value();
139 }
140
SetVideoSize(int32_t width,int32_t height)141 int32_t TransCoderServer::SetVideoSize(int32_t width, int32_t height)
142 {
143 std::lock_guard<std::mutex> lock(mutex_);
144 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
145 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
146 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
147 config_.width = width;
148 config_.height = height;
149 VideoRectangle vidSize(width, height);
150 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
151 return transCoderEngine_->Configure(vidSize);
152 });
153 int32_t ret = taskQue_.EnqueueTask(task);
154 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
155
156 auto result = task->GetResult();
157 return result.Value();
158 }
159
SetVideoEncodingBitRate(int32_t rate)160 int32_t TransCoderServer::SetVideoEncodingBitRate(int32_t rate)
161 {
162 std::lock_guard<std::mutex> lock(mutex_);
163 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
164 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
165 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
166 config_.videoBitRate = rate;
167 VideoBitRate vidBitRate(rate);
168 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
169 return transCoderEngine_->Configure(vidBitRate);
170 });
171 int32_t ret = taskQue_.EnqueueTask(task);
172 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
173
174 auto result = task->GetResult();
175 return result.Value();
176 }
177
SetAudioEncoder(AudioCodecFormat encoder)178 int32_t TransCoderServer::SetAudioEncoder(AudioCodecFormat encoder)
179 {
180 std::lock_guard<std::mutex> lock(mutex_);
181 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
182 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
183 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
184 config_.audioCodec = encoder;
185 AudioEnc audEnc(encoder);
186 MEDIA_LOGD("set audio encoder encoder:%{public}d", encoder);
187 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
188 return transCoderEngine_->Configure(audEnc);
189 });
190 int32_t ret = taskQue_.EnqueueTask(task);
191 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
192
193 auto result = task->GetResult();
194 return result.Value();
195 }
196
SetAudioEncodingBitRate(int32_t bitRate)197 int32_t TransCoderServer::SetAudioEncodingBitRate(int32_t bitRate)
198 {
199 std::lock_guard<std::mutex> lock(mutex_);
200 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
201 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
202 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
203 config_.audioBitRate = bitRate;
204 AudioBitRate audBitRate(bitRate);
205 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
206 return transCoderEngine_->Configure(audBitRate);
207 });
208 int32_t ret = taskQue_.EnqueueTask(task);
209 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
210
211 auto result = task->GetResult();
212 return result.Value();
213 }
214
SetOutputFormat(OutputFormatType format)215 int32_t TransCoderServer::SetOutputFormat(OutputFormatType format)
216 {
217 std::lock_guard<std::mutex> lock(mutex_);
218 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED, MSERR_INVALID_OPERATION,
219 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
220 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
221 config_.format = format;
222 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
223 return transCoderEngine_->SetOutputFormat(format);
224 });
225 int32_t ret = taskQue_.EnqueueTask(task);
226 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
227
228 auto result = task->GetResult();
229 ret = result.Value();
230 status_ = (ret == MSERR_OK ? REC_CONFIGURED : REC_INITIALIZED);
231 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
232 return ret;
233 }
234
SetInputFile(int32_t fd,int64_t offset,int64_t size)235 int32_t TransCoderServer::SetInputFile(int32_t fd, int64_t offset, int64_t size)
236 {
237 std::lock_guard<std::mutex> lock(mutex_);
238 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED, MSERR_INVALID_OPERATION,
239 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
240 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
241 config_.srcFd = fd;
242 config_.srcFdOffset = offset;
243 config_.srcFdSize = size;
244 uriHelper_ = std::make_unique<UriHelper>(fd, offset, size);
245 CHECK_AND_RETURN_RET_LOG(uriHelper_->AccessCheck(UriHelper::URI_READ),
246 MSERR_INVALID_VAL, "Failed to read the fd");
247 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
248 return transCoderEngine_->SetInputFile(uriHelper_->FormattedUri());
249 });
250 int32_t ret = taskQue_.EnqueueTask(task);
251 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
252
253 auto result = task->GetResult();
254 return result.Value();
255 }
256
SetOutputFile(int32_t fd)257 int32_t TransCoderServer::SetOutputFile(int32_t fd)
258 {
259 std::lock_guard<std::mutex> lock(mutex_);
260 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED, MSERR_INVALID_OPERATION,
261 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
262 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
263 config_.dstUrl = fd;
264 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
265 return transCoderEngine_->SetOutputFile(fd);
266 });
267 int32_t ret = taskQue_.EnqueueTask(task);
268 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
269
270 auto result = task->GetResult();
271 return result.Value();
272 }
273
SetTransCoderCallback(const std::shared_ptr<TransCoderCallback> & callback)274 int32_t TransCoderServer::SetTransCoderCallback(const std::shared_ptr<TransCoderCallback> &callback)
275 {
276 std::lock_guard<std::mutex> lock(mutex_);
277 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED || status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
278 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
279 {
280 std::lock_guard<std::mutex> cbLock(cbMutex_);
281 transCoderCb_ = callback;
282 }
283
284 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
285 std::shared_ptr<ITransCoderEngineObs> obs = shared_from_this();
286 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
287 return transCoderEngine_->SetObs(obs);
288 });
289 int32_t ret = taskQue_.EnqueueTask(task);
290 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
291
292 auto result = task->GetResult();
293 return result.Value();
294 }
295
Prepare()296 int32_t TransCoderServer::Prepare()
297 {
298 std::lock_guard<std::mutex> lock(mutex_);
299 MediaTrace trace("TransCoderServer::Prepare");
300 CHECK_AND_RETURN_RET_LOG(status_ != REC_PREPARED, MSERR_INVALID_OPERATION, "Can not repeat Prepare");
301 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
302 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
303 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
304 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
305 return transCoderEngine_->Prepare();
306 });
307 int32_t ret = taskQue_.EnqueueTask(task);
308 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
309
310 auto result = task->GetResult();
311 ret = result.Value();
312 status_ = (ret == MSERR_OK ? REC_PREPARED : REC_ERROR);
313 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
314 return ret;
315 }
316
Start()317 int32_t TransCoderServer::Start()
318 {
319 std::lock_guard<std::mutex> lock(mutex_);
320 MediaTrace trace("TransCoderServer::Start");
321 CHECK_AND_RETURN_RET_LOG(status_ != REC_TRANSCODERING, MSERR_INVALID_OPERATION, "Can not repeat Start");
322 CHECK_AND_RETURN_RET_LOG(status_ == REC_PREPARED, MSERR_INVALID_OPERATION,
323 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
324 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
325 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
326 return transCoderEngine_->Start();
327 });
328 int32_t ret = taskQue_.EnqueueTask(task);
329 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
330
331 auto result = task->GetResult();
332 ret = result.Value();
333 status_ = (ret == MSERR_OK ? REC_TRANSCODERING : REC_ERROR);
334 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
335 return ret;
336 }
337
Pause()338 int32_t TransCoderServer::Pause()
339 {
340 MediaTrace trace("TransCoderServer::Pause");
341 std::lock_guard<std::mutex> lock(mutex_);
342 CHECK_AND_RETURN_RET_LOG(status_ != REC_PAUSED, MSERR_INVALID_OPERATION, "Can not repeat Pause");
343 CHECK_AND_RETURN_RET_LOG(status_ == REC_TRANSCODERING, MSERR_INVALID_OPERATION,
344 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
345 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
346 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
347 return transCoderEngine_->Pause();
348 });
349 int32_t ret = taskQue_.EnqueueTask(task);
350 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
351
352 auto result = task->GetResult();
353 ret = result.Value();
354 status_ = (ret == MSERR_OK ? REC_PAUSED : REC_ERROR);
355 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
356 return ret;
357 }
358
Resume()359 int32_t TransCoderServer::Resume()
360 {
361 MediaTrace trace("TransCoderServer::Resume");
362 std::lock_guard<std::mutex> lock(mutex_);
363 CHECK_AND_RETURN_RET_LOG(status_ != REC_TRANSCODERING, MSERR_INVALID_OPERATION, "Can not repeat Resume");
364 CHECK_AND_RETURN_RET_LOG(status_ == REC_TRANSCODERING || status_ == REC_PAUSED, MSERR_INVALID_OPERATION,
365 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
366 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
367 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
368 return transCoderEngine_->Resume();
369 });
370 int32_t ret = taskQue_.EnqueueTask(task);
371 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
372
373 auto result = task->GetResult();
374 ret = result.Value();
375 status_ = (ret == MSERR_OK ? REC_TRANSCODERING : REC_ERROR);
376 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
377 return ret;
378 }
379
Cancel()380 int32_t TransCoderServer::Cancel()
381 {
382 std::lock_guard<std::mutex> lock(mutex_);
383 MediaTrace trace("TransCoderServer::Cancel");
384 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
385 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
386 return transCoderEngine_->Cancel();
387 });
388 int32_t ret = taskQue_.EnqueueTask(task);
389 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
390
391 auto result = task->GetResult();
392 ret = result.Value();
393 status_ = (ret == MSERR_OK ? REC_INITIALIZED : REC_ERROR);
394 BehaviorEventWrite(GetStatusDescription(status_), "TransCoder");
395 return ret;
396 }
397
Release()398 int32_t TransCoderServer::Release()
399 {
400 std::lock_guard<std::mutex> lock(mutex_);
401 ReleaseInner();
402 return MSERR_OK;
403 }
404
ReleaseInner()405 void TransCoderServer::ReleaseInner()
406 {
407 MEDIA_LOGI("ReleaseInner enter");
408 if (transCoderEngine_ == nullptr) {
409 return;
410 }
411 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
412 int32_t ret = transCoderEngine_->Cancel();
413 transCoderEngine_ = nullptr;
414 return ret;
415 });
416 (void)taskQue_.EnqueueTask(task);
417 (void)task->GetResult();
418 }
419
DumpInfo(int32_t fd)420 int32_t TransCoderServer::DumpInfo(int32_t fd)
421 {
422 std::string dumpString;
423 dumpString += "In TransCoderServer::DumpInfo\n";
424 dumpString += "TransCoderServer current state is: " + std::to_string(status_) + "\n";
425 if (lastErrMsg_.size() != 0) {
426 dumpString += "TransCoderServer last error is: " + lastErrMsg_ + "\n";
427 }
428 dumpString += "TransCoderServer videoCodec is: " + std::to_string(config_.videoCodec) + "\n";
429 dumpString += "TransCoderServer audioCodec is: " + std::to_string(config_.audioCodec) + "\n";
430 dumpString += "TransCoderServer width is: " + std::to_string(config_.width) + "\n";
431 dumpString += "TransCoderServer height is: " + std::to_string(config_.height) + "\n";
432 dumpString += "TransCoderServer bitRate is: " + std::to_string(config_.videoBitRate) + "\n";
433 dumpString += "TransCoderServer audioBitRate is: " + std::to_string(config_.audioBitRate) + "\n";
434 dumpString += "TransCoderServer format is: " + std::to_string(config_.format) + "\n";
435 write(fd, dumpString.c_str(), dumpString.size());
436
437 return MSERR_OK;
438 }
439 } // namespace Media
440 } // namespace OHOS
441