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 return MSERR_OK;
94 }
95
GetStatusDescription(OHOS::Media::TransCoderServer::RecStatus status)96 const std::string& TransCoderServer::GetStatusDescription(OHOS::Media::TransCoderServer::RecStatus status)
97 {
98 static const std::string ILLEGAL_STATE = "PLAYER_STATUS_ILLEGAL";
99 CHECK_AND_RETURN_RET(status >= OHOS::Media::TransCoderServer::REC_INITIALIZED &&
100 status <= OHOS::Media::TransCoderServer::REC_ERROR, ILLEGAL_STATE);
101
102 return TRANSCODER_STATE_MAP.find(status)->second;
103 }
104
OnError(TransCoderErrorType errorType,int32_t errorCode)105 void TransCoderServer::OnError(TransCoderErrorType errorType, int32_t errorCode)
106 {
107 (void)errorType;
108 std::lock_guard<std::mutex> lock(cbMutex_);
109 lastErrMsg_ = MSErrorToExtErrorString(static_cast<MediaServiceErrCode>(errorCode));
110 CHECK_AND_RETURN(transCoderCb_ != nullptr);
111 transCoderCb_->OnError(errorCode, lastErrMsg_);
112 }
113
OnInfo(TransCoderOnInfoType type,int32_t extra)114 void TransCoderServer::OnInfo(TransCoderOnInfoType type, int32_t extra)
115 {
116 std::lock_guard<std::mutex> lock(cbMutex_);
117 CHECK_AND_RETURN(transCoderCb_ != nullptr);
118 transCoderCb_->OnInfo(type, extra);
119 }
120
SetVideoEncoder(VideoCodecFormat encoder)121 int32_t TransCoderServer::SetVideoEncoder(VideoCodecFormat encoder)
122 {
123 std::lock_guard<std::mutex> lock(mutex_);
124 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
125 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
126 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
127 config_.videoCodec = encoder;
128 VideoEnc vidEnc(encoder);
129 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
130 return transCoderEngine_->Configure(vidEnc);
131 });
132 int32_t ret = taskQue_.EnqueueTask(task);
133 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
134
135 auto result = task->GetResult();
136 return result.Value();
137 }
138
SetVideoSize(int32_t width,int32_t height)139 int32_t TransCoderServer::SetVideoSize(int32_t width, int32_t height)
140 {
141 std::lock_guard<std::mutex> lock(mutex_);
142 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
143 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
144 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
145 config_.width = width;
146 config_.height = height;
147 VideoRectangle vidSize(width, height);
148 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
149 return transCoderEngine_->Configure(vidSize);
150 });
151 int32_t ret = taskQue_.EnqueueTask(task);
152 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
153
154 auto result = task->GetResult();
155 return result.Value();
156 }
157
SetVideoEncodingBitRate(int32_t rate)158 int32_t TransCoderServer::SetVideoEncodingBitRate(int32_t rate)
159 {
160 std::lock_guard<std::mutex> lock(mutex_);
161 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
162 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
163 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
164 config_.videoBitRate = rate;
165 VideoBitRate vidBitRate(rate);
166 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
167 return transCoderEngine_->Configure(vidBitRate);
168 });
169 int32_t ret = taskQue_.EnqueueTask(task);
170 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
171
172 auto result = task->GetResult();
173 return result.Value();
174 }
175
SetAudioEncoder(AudioCodecFormat encoder)176 int32_t TransCoderServer::SetAudioEncoder(AudioCodecFormat encoder)
177 {
178 std::lock_guard<std::mutex> lock(mutex_);
179 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
180 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
181 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
182 config_.audioCodec = encoder;
183 AudioEnc audEnc(encoder);
184 MEDIA_LOGD("set audio encoder encoder:%{public}d", encoder);
185 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
186 return transCoderEngine_->Configure(audEnc);
187 });
188 int32_t ret = taskQue_.EnqueueTask(task);
189 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
190
191 auto result = task->GetResult();
192 return result.Value();
193 }
194
SetAudioEncodingBitRate(int32_t bitRate)195 int32_t TransCoderServer::SetAudioEncodingBitRate(int32_t bitRate)
196 {
197 std::lock_guard<std::mutex> lock(mutex_);
198 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
199 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
200 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
201 config_.audioBitRate = bitRate;
202 AudioBitRate audBitRate(bitRate);
203 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
204 return transCoderEngine_->Configure(audBitRate);
205 });
206 int32_t ret = taskQue_.EnqueueTask(task);
207 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
208
209 auto result = task->GetResult();
210 return result.Value();
211 }
212
SetOutputFormat(OutputFormatType format)213 int32_t TransCoderServer::SetOutputFormat(OutputFormatType format)
214 {
215 std::lock_guard<std::mutex> lock(mutex_);
216 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED, MSERR_INVALID_OPERATION,
217 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
218 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
219 config_.format = format;
220 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
221 return transCoderEngine_->SetOutputFormat(format);
222 });
223 int32_t ret = taskQue_.EnqueueTask(task);
224 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
225
226 auto result = task->GetResult();
227 ret = result.Value();
228 status_ = (ret == MSERR_OK ? REC_CONFIGURED : REC_INITIALIZED);
229 return ret;
230 }
231
SetInputFile(int32_t fd,int64_t offset,int64_t size)232 int32_t TransCoderServer::SetInputFile(int32_t fd, int64_t offset, int64_t size)
233 {
234 std::lock_guard<std::mutex> lock(mutex_);
235 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED, MSERR_INVALID_OPERATION,
236 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
237 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
238 config_.srcFd = fd;
239 config_.srcFdOffset = offset;
240 config_.srcFdSize = size;
241 uriHelper_ = std::make_unique<UriHelper>(fd, offset, size);
242 CHECK_AND_RETURN_RET_LOG(uriHelper_->AccessCheck(UriHelper::URI_READ),
243 MSERR_INVALID_VAL, "Failed to read the fd");
244 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
245 return transCoderEngine_->SetInputFile(uriHelper_->FormattedUri());
246 });
247 int32_t ret = taskQue_.EnqueueTask(task);
248 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
249
250 auto result = task->GetResult();
251 return result.Value();
252 }
253
SetOutputFile(int32_t fd)254 int32_t TransCoderServer::SetOutputFile(int32_t fd)
255 {
256 std::lock_guard<std::mutex> lock(mutex_);
257 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED, MSERR_INVALID_OPERATION,
258 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
259 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
260 config_.dstUrl = fd;
261 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
262 return transCoderEngine_->SetOutputFile(fd);
263 });
264 int32_t ret = taskQue_.EnqueueTask(task);
265 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
266
267 auto result = task->GetResult();
268 return result.Value();
269 }
270
SetTransCoderCallback(const std::shared_ptr<TransCoderCallback> & callback)271 int32_t TransCoderServer::SetTransCoderCallback(const std::shared_ptr<TransCoderCallback> &callback)
272 {
273 std::lock_guard<std::mutex> lock(mutex_);
274 CHECK_AND_RETURN_RET_LOG(status_ == REC_INITIALIZED || status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
275 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
276 {
277 std::lock_guard<std::mutex> cbLock(cbMutex_);
278 transCoderCb_ = callback;
279 }
280
281 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
282 std::shared_ptr<ITransCoderEngineObs> obs = shared_from_this();
283 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
284 return transCoderEngine_->SetObs(obs);
285 });
286 int32_t ret = taskQue_.EnqueueTask(task);
287 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
288
289 auto result = task->GetResult();
290 return result.Value();
291 }
292
Prepare()293 int32_t TransCoderServer::Prepare()
294 {
295 std::lock_guard<std::mutex> lock(mutex_);
296 MediaTrace trace("TransCoderServer::Prepare");
297 CHECK_AND_RETURN_RET_LOG(status_ != REC_PREPARED, MSERR_INVALID_OPERATION, "Can not repeat Prepare");
298 CHECK_AND_RETURN_RET_LOG(status_ == REC_CONFIGURED, MSERR_INVALID_OPERATION,
299 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
300 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
301 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
302 return transCoderEngine_->Prepare();
303 });
304 int32_t ret = taskQue_.EnqueueTask(task);
305 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
306
307 auto result = task->GetResult();
308 ret = result.Value();
309 status_ = (ret == MSERR_OK ? REC_PREPARED : REC_ERROR);
310 return ret;
311 }
312
Start()313 int32_t TransCoderServer::Start()
314 {
315 std::lock_guard<std::mutex> lock(mutex_);
316 MediaTrace trace("TransCoderServer::Start");
317 CHECK_AND_RETURN_RET_LOG(status_ != REC_TRANSCODERING, MSERR_INVALID_OPERATION, "Can not repeat Start");
318 CHECK_AND_RETURN_RET_LOG(status_ == REC_PREPARED, MSERR_INVALID_OPERATION,
319 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
320 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
321 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
322 return transCoderEngine_->Start();
323 });
324 int32_t ret = taskQue_.EnqueueTask(task);
325 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
326
327 auto result = task->GetResult();
328 ret = result.Value();
329 status_ = (ret == MSERR_OK ? REC_TRANSCODERING : REC_ERROR);
330 return ret;
331 }
332
Pause()333 int32_t TransCoderServer::Pause()
334 {
335 MediaTrace trace("TransCoderServer::Pause");
336 std::lock_guard<std::mutex> lock(mutex_);
337 CHECK_AND_RETURN_RET_LOG(status_ != REC_PAUSED, MSERR_INVALID_OPERATION, "Can not repeat Pause");
338 CHECK_AND_RETURN_RET_LOG(status_ == REC_TRANSCODERING, MSERR_INVALID_OPERATION,
339 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
340 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
341 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
342 return transCoderEngine_->Pause();
343 });
344 int32_t ret = taskQue_.EnqueueTask(task);
345 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
346
347 auto result = task->GetResult();
348 ret = result.Value();
349 status_ = (ret == MSERR_OK ? REC_PAUSED : REC_ERROR);
350 return ret;
351 }
352
Resume()353 int32_t TransCoderServer::Resume()
354 {
355 MediaTrace trace("TransCoderServer::Resume");
356 std::lock_guard<std::mutex> lock(mutex_);
357 CHECK_AND_RETURN_RET_LOG(status_ != REC_TRANSCODERING, MSERR_INVALID_OPERATION, "Can not repeat Resume");
358 CHECK_AND_RETURN_RET_LOG(status_ == REC_TRANSCODERING || status_ == REC_PAUSED, MSERR_INVALID_OPERATION,
359 "invalid status, current status is %{public}s", GetStatusDescription(status_).c_str());
360 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
361 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
362 return transCoderEngine_->Resume();
363 });
364 int32_t ret = taskQue_.EnqueueTask(task);
365 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
366
367 auto result = task->GetResult();
368 ret = result.Value();
369 status_ = (ret == MSERR_OK ? REC_TRANSCODERING : REC_ERROR);
370 return ret;
371 }
372
Cancel()373 int32_t TransCoderServer::Cancel()
374 {
375 std::lock_guard<std::mutex> lock(mutex_);
376 MediaTrace trace("TransCoderServer::Cancel");
377 CHECK_AND_RETURN_RET_LOG(transCoderEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
378 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
379 return transCoderEngine_->Cancel();
380 });
381 int32_t ret = taskQue_.EnqueueTask(task);
382 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "EnqueueTask failed");
383
384 auto result = task->GetResult();
385 ret = result.Value();
386 status_ = (ret == MSERR_OK ? REC_INITIALIZED : REC_ERROR);
387 return ret;
388 }
389
Release()390 int32_t TransCoderServer::Release()
391 {
392 std::lock_guard<std::mutex> lock(mutex_);
393 ReleaseInner();
394 return MSERR_OK;
395 }
396
ReleaseInner()397 void TransCoderServer::ReleaseInner()
398 {
399 MEDIA_LOGI("ReleaseInner enter");
400 if (transCoderEngine_ == nullptr) {
401 return;
402 }
403 auto task = std::make_shared<TaskHandler<int32_t>>([&, this] {
404 int32_t ret = transCoderEngine_->Cancel();
405 transCoderEngine_ = nullptr;
406 return ret;
407 });
408 (void)taskQue_.EnqueueTask(task);
409 (void)task->GetResult();
410 }
411
DumpInfo(int32_t fd)412 int32_t TransCoderServer::DumpInfo(int32_t fd)
413 {
414 std::string dumpString;
415 dumpString += "In TransCoderServer::DumpInfo\n";
416 dumpString += "TransCoderServer current state is: " + std::to_string(status_) + "\n";
417 if (lastErrMsg_.size() != 0) {
418 dumpString += "TransCoderServer last error is: " + lastErrMsg_ + "\n";
419 }
420 dumpString += "TransCoderServer videoCodec is: " + std::to_string(config_.videoCodec) + "\n";
421 dumpString += "TransCoderServer audioCodec is: " + std::to_string(config_.audioCodec) + "\n";
422 dumpString += "TransCoderServer width is: " + std::to_string(config_.width) + "\n";
423 dumpString += "TransCoderServer height is: " + std::to_string(config_.height) + "\n";
424 dumpString += "TransCoderServer bitRate is: " + std::to_string(config_.videoBitRate) + "\n";
425 dumpString += "TransCoderServer audioBitRate is: " + std::to_string(config_.audioBitRate) + "\n";
426 dumpString += "TransCoderServer format is: " + std::to_string(config_.format) + "\n";
427 write(fd, dumpString.c_str(), dumpString.size());
428
429 return MSERR_OK;
430 }
431 } // namespace Media
432 } // namespace OHOS
433