1 /*
2 * Copyright (c) 2024-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 #include "hitranscoder_impl.h"
16 #include "sync_fence.h"
17 #include <sys/syscall.h>
18 #include "directory_ex.h"
19 #include "osal/task/jobutils.h"
20 #include "osal/task/task.h"
21 #include "media_utils.h"
22 #include "media_dfx.h"
23 #include "meta/video_types.h"
24 #include "meta/any.h"
25 #include "common/log.h"
26 #include "avcodec_info.h"
27 #include "osal/task/pipeline_threadpool.h"
28
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_ONLY_PRERELEASE, LOG_DOMAIN_SYSTEM_PLAYER, "HiTransCoder" };
31 constexpr int32_t REPORT_PROGRESS_INTERVAL = 100;
32 constexpr int32_t TRANSCODER_COMPLETE_PROGRESS = 100;
33 constexpr int32_t MINIMUM_WIDTH_HEIGHT = 240;
34 constexpr int32_t HEIGHT_480 = 480;
35 constexpr int32_t HEIGHT_720 = 720;
36 constexpr int32_t HEIGHT_1080 = 1080;
37 constexpr int32_t VIDEO_BITRATE_1M = 1024 * 1024;
38 constexpr int32_t VIDEO_BITRATE_2M = 2 * VIDEO_BITRATE_1M;
39 constexpr int32_t VIDEO_BITRATE_4M = 4 * VIDEO_BITRATE_1M;
40 constexpr int32_t VIDEO_BITRATE_8M = 8 * VIDEO_BITRATE_1M;
41 constexpr int32_t INVALID_AUDIO_BITRATE = INT32_MAX; // Invalid value defined in the napi and capi.
42 constexpr int32_t DEFAULT_AUDIO_BITRATE = 48000;
43 }
44
45 namespace OHOS {
46 namespace Media {
47 static const std::unordered_set<std::string> AVMETA_KEY = {
48 { Tag::MEDIA_ALBUM },
49 { Tag::MEDIA_ALBUM_ARTIST },
50 { Tag::MEDIA_ARTIST },
51 { Tag::MEDIA_AUTHOR },
52 { Tag::MEDIA_COMPOSER },
53 { Tag::MEDIA_DATE },
54 { Tag::MEDIA_CREATION_TIME },
55 { Tag::MEDIA_DURATION },
56 { Tag::MEDIA_GENRE },
57 { Tag::MIME_TYPE },
58 { Tag::AUDIO_SAMPLE_RATE },
59 { Tag::MEDIA_TITLE },
60 { Tag::VIDEO_HEIGHT },
61 { Tag::VIDEO_WIDTH },
62 { Tag::VIDEO_FRAME_RATE },
63 { Tag::VIDEO_ROTATION },
64 { Tag::VIDEO_IS_HDR_VIVID },
65 { Tag::MEDIA_LONGITUDE },
66 { Tag::MEDIA_LATITUDE },
67 { Tag::MEDIA_BITRATE },
68 { Tag::AUDIO_CHANNEL_COUNT },
69 { Tag::AUDIO_SAMPLE_FORMAT },
70 { Tag::AUDIO_BITS_PER_CODED_SAMPLE },
71 { Tag::AUDIO_BITS_PER_RAW_SAMPLE },
72 { "customInfo" },
73 };
74
75 class TransCoderEventReceiver : public Pipeline::EventReceiver {
76 public:
TransCoderEventReceiver(HiTransCoderImpl * hiTransCoderImpl,std::string transcoderId)77 explicit TransCoderEventReceiver(HiTransCoderImpl *hiTransCoderImpl, std::string transcoderId)
78 {
79 MEDIA_LOG_I("TransCoderEventReceiver ctor called.");
80 std::unique_lock<std::shared_mutex> lk(cbMutex_);
81 hiTransCoderImpl_ = hiTransCoderImpl;
82 task_ = std::make_unique<Task>("TransCoderEventReceiver", transcoderId, TaskType::GLOBAL,
83 OHOS::Media::TaskPriority::HIGH, false);
84 }
85
OnEvent(const Event & event)86 void OnEvent(const Event &event) override
87 {
88 MEDIA_LOG_D("TransCoderEventReceiver OnEvent");
89 FALSE_RETURN_MSG(task_ != nullptr, "task_ is nullptr");
90 task_->SubmitJobOnce([this, event] {
91 std::shared_lock<std::shared_mutex> lk(cbMutex_);
92 FALSE_RETURN(hiTransCoderImpl_ != nullptr);
93 hiTransCoderImpl_->OnEvent(event);
94 });
95 }
96
NotifyRelease()97 void NotifyRelease() override
98 {
99 MEDIA_LOG_D("TransCoderEventReceiver NotifyRelease.");
100 std::unique_lock<std::shared_mutex> lk(cbMutex_);
101 hiTransCoderImpl_ = nullptr;
102 }
103
104 private:
105 std::shared_mutex cbMutex_ {};
106 HiTransCoderImpl *hiTransCoderImpl_;
107 std::unique_ptr<Task> task_;
108 };
109
110 class TransCoderFilterCallback : public Pipeline::FilterCallback {
111 public:
TransCoderFilterCallback(HiTransCoderImpl * hiTransCoderImpl)112 explicit TransCoderFilterCallback(HiTransCoderImpl *hiTransCoderImpl)
113 {
114 MEDIA_LOG_I("TransCoderFilterCallback ctor called");
115 std::unique_lock<std::shared_mutex> lk(cbMutex_);
116 hiTransCoderImpl_ = hiTransCoderImpl;
117 }
118
OnCallback(const std::shared_ptr<Pipeline::Filter> & filter,Pipeline::FilterCallBackCommand cmd,Pipeline::StreamType outType)119 Status OnCallback(const std::shared_ptr<Pipeline::Filter>& filter, Pipeline::FilterCallBackCommand cmd,
120 Pipeline::StreamType outType) override
121 {
122 std::shared_lock<std::shared_mutex> lk(cbMutex_);
123 FALSE_RETURN_V(hiTransCoderImpl_ != nullptr, Status::OK); // hiTransCoderImpl_ is destructed
124 return hiTransCoderImpl_->OnCallback(filter, cmd, outType);
125 }
126
NotifyRelease()127 void NotifyRelease() override
128 {
129 MEDIA_LOG_D("PlayerEventReceiver NotifyRelease.");
130 std::unique_lock<std::shared_mutex> lk(cbMutex_);
131 hiTransCoderImpl_ = nullptr;
132 }
133
134 private:
135 std::shared_mutex cbMutex_ {};
136 HiTransCoderImpl *hiTransCoderImpl_;
137 };
138
HiTransCoderImpl(int32_t appUid,int32_t appPid,uint32_t appTokenId,uint64_t appFullTokenId)139 HiTransCoderImpl::HiTransCoderImpl(int32_t appUid, int32_t appPid, uint32_t appTokenId, uint64_t appFullTokenId)
140 : appUid_(appUid), appPid_(appPid), appTokenId_(appTokenId), appFullTokenId_(appFullTokenId)
141 {
142 MEDIA_LOG_I("HiTransCoderImpl");
143 pipeline_ = std::make_shared<Pipeline::Pipeline>();
144 transCoderId_ = std::string("Trans_") + std::to_string(OHOS::Media::Pipeline::Pipeline::GetNextPipelineId());
145 }
146
~HiTransCoderImpl()147 HiTransCoderImpl::~HiTransCoderImpl()
148 {
149 if (demuxerFilter_) {
150 pipeline_->RemoveHeadFilter(demuxerFilter_);
151 }
152 if (transCoderEventReceiver_ != nullptr) {
153 transCoderEventReceiver_->NotifyRelease();
154 }
155 if (transCoderFilterCallback_ != nullptr) {
156 transCoderFilterCallback_->NotifyRelease();
157 }
158 PipeLineThreadPool::GetInstance().DestroyThread(transCoderId_);
159 MEDIA_LOG_I("~HiTransCoderImpl");
160 }
161
SetInstanceId(uint64_t instanceId)162 void HiTransCoderImpl::SetInstanceId(uint64_t instanceId)
163 {
164 instanceId_ = instanceId;
165 }
166
Init()167 int32_t HiTransCoderImpl::Init()
168 {
169 MEDIA_LOG_I("HiTransCoderImpl::Init()");
170 MediaTrace trace("HiTransCoderImpl::Init()");
171 transCoderEventReceiver_ = std::make_shared<TransCoderEventReceiver>(this, transCoderId_);
172 transCoderFilterCallback_ = std::make_shared<TransCoderFilterCallback>(this);
173 FALSE_RETURN_V_MSG_E(transCoderEventReceiver_ != nullptr && transCoderFilterCallback_ != nullptr,
174 static_cast<int32_t>(Status::ERROR_NO_MEMORY), "fail to init hiTransCoderImpl");
175 pipeline_->Init(transCoderEventReceiver_, transCoderFilterCallback_, transCoderId_);
176 callbackLooper_ = std::make_shared<HiTransCoderCallbackLooper>();
177 FALSE_RETURN_V_MSG_E(callbackLooper_ != nullptr, static_cast<int32_t>(Status::ERROR_NO_MEMORY),
178 "fail to create callbackLooper");
179 callbackLooper_->SetTransCoderEngine(this, transCoderId_);
180 return static_cast<int32_t>(Status::OK);
181 }
182
GetRealPath(const std::string & url,std::string & realUrlPath) const183 int32_t HiTransCoderImpl::GetRealPath(const std::string &url, std::string &realUrlPath) const
184 {
185 std::string fileHead = "file://";
186 std::string tempUrlPath;
187
188 if (url.find(fileHead) == 0 && url.size() > fileHead.size()) {
189 tempUrlPath = url.substr(fileHead.size());
190 } else {
191 tempUrlPath = url;
192 }
193 FALSE_RETURN_V_MSG_E(tempUrlPath.find("..") == std::string::npos, MSERR_FILE_ACCESS_FAILED,
194 "invalid url. The Url (%{private}s) path may be invalid.", tempUrlPath.c_str());
195 bool ret = PathToRealPath(tempUrlPath, realUrlPath);
196 FALSE_RETURN_V_MSG_E(ret, MSERR_OPEN_FILE_FAILED, "invalid url. The Url (%{private}s) path may be invalid.",
197 url.c_str());
198 FALSE_RETURN_V(access(realUrlPath.c_str(), R_OK) == 0, MSERR_FILE_ACCESS_FAILED);
199 return MSERR_OK;
200 }
201
SetInputFile(const std::string & url)202 int32_t HiTransCoderImpl::SetInputFile(const std::string &url)
203 {
204 MEDIA_LOG_I("HiTransCoderImpl::SetInputFile()");
205 MediaTrace trace("HiTransCoderImpl::SetInputFile()");
206 inputFile_ = url;
207 if (url.find("://") == std::string::npos || url.find("file://") == 0) {
208 std::string realUriPath;
209 int32_t result = GetRealPath(url, realUriPath);
210 FALSE_RETURN_V_MSG_E(result == MSERR_OK, result, "SetInputFile error: GetRealPath error");
211 inputFile_ = "file://" + realUriPath;
212 }
213 std::shared_ptr<MediaSource> mediaSource = std::make_shared<MediaSource>(inputFile_);
214 demuxerFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::DemuxerFilter>("builtin.player.demuxer",
215 Pipeline::FilterType::FILTERTYPE_DEMUXER);
216 if (demuxerFilter_ == nullptr) {
217 MEDIA_LOG_E("demuxerFilter_ is nullptr");
218 return MSERR_NO_MEMORY;
219 }
220 pipeline_->AddHeadFilters({demuxerFilter_});
221 demuxerFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
222 (void)demuxerFilter_->SetTranscoderMode();
223 int32_t ret = TransTranscoderStatus(demuxerFilter_->SetDataSource(mediaSource));
224 if (ret != MSERR_OK) {
225 MEDIA_LOG_E("SetInputFile error: demuxerFilter_->SetDataSource error");
226 CollectionErrorInfo(ret, "SetInputFile error");
227 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, MSERR_UNSUPPORT_SOURCE});
228 return ret;
229 }
230 int64_t duration = 0;
231 if (demuxerFilter_->GetDuration(duration)) {
232 durationMs_ = Plugins::HstTime2Us(duration);
233 } else {
234 MEDIA_LOG_E("Get media duration failed");
235 }
236 ret = TransTranscoderStatus(ConfigureVideoAudioMetaData());
237 CreateMediaInfo(CallType::AVTRANSCODER, appUid_, instanceId_);
238 return ret;
239 }
240
ConfigureMetaDataToTrackFormat(const std::shared_ptr<Meta> & globalInfo,const std::vector<std::shared_ptr<Meta>> & trackInfos)241 void HiTransCoderImpl::ConfigureMetaDataToTrackFormat(const std::shared_ptr<Meta> &globalInfo,
242 const std::vector<std::shared_ptr<Meta>> &trackInfos)
243 {
244 FALSE_RETURN_MSG(
245 globalInfo != nullptr && trackInfos.size() != 0, "globalInfo or trackInfos are invalid.");
246
247 bool isInitializeVideoEncFormat = false;
248 bool isInitializeAudioEncFormat = false;
249 isExistVideoTrack_ = false;
250 (void)SetValueByType(globalInfo, muxerFormat_);
251 for (size_t index = 0; index < trackInfos.size(); index++) {
252 MEDIA_LOG_I("trackInfos index: %{public}zu", index);
253 std::shared_ptr<Meta> meta = trackInfos[index];
254 FALSE_RETURN_MSG(meta != nullptr, "meta is invalid, index: %zu", index);
255 std::string trackMime;
256 if (!meta->GetData(Tag::MIME_TYPE, trackMime)) {
257 MEDIA_LOG_W("mimeType not found, index: %zu", index);
258 continue;
259 }
260 if (!isInitializeVideoEncFormat && (trackMime.find("video/") == 0)) {
261 (void)SetValueByType(meta, videoEncFormat_);
262 (void)SetValueByType(meta, srcVideoFormat_);
263 (void)SetValueByType(meta, muxerFormat_);
264 meta->GetData(Tag::VIDEO_WIDTH, inputVideoWidth_);
265 meta->GetData(Tag::VIDEO_HEIGHT, inputVideoHeight_);
266 isExistVideoTrack_ = true;
267 isInitializeVideoEncFormat = true;
268 } else if (!isInitializeAudioEncFormat && (trackMime.find("audio/") == 0)) {
269 (void)SetValueByType(meta, audioEncFormat_);
270 (void)SetValueByType(meta, srcAudioFormat_);
271 (void)SetValueByType(meta, muxerFormat_);
272 isInitializeAudioEncFormat = true;
273 }
274 }
275 if (!isExistVideoTrack_) {
276 MEDIA_LOG_E("No video track found.");
277 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, MSERR_UNSUPPORT_VID_SRC_TYPE});
278 }
279 }
280
ConfigureDefaultParameter()281 void HiTransCoderImpl::ConfigureDefaultParameter()
282 {
283 ConfigureVideoDefaultEncFormat();
284 ConfigureVideoBitrate();
285 ConfigureAudioDefaultEncFormat();
286 }
287
ConfigureVideoDefaultEncFormat()288 void HiTransCoderImpl::ConfigureVideoDefaultEncFormat()
289 {
290 std::string videoMime;
291 videoEncFormat_->GetData(Tag::MIME_TYPE, videoMime);
292 FALSE_RETURN_NOLOG(videoMime != Plugins::MimeType::VIDEO_HEVC && videoMime != Plugins::MimeType::VIDEO_AVC);
293 MEDIA_LOG_I("Set the default videoEnc format, " PUBLIC_LOG_S " to " PUBLIC_LOG_S, videoMime.c_str(),
294 Plugins::MimeType::VIDEO_AVC);
295 videoEncFormat_->Set<Tag::MIME_TYPE>(Plugins::MimeType::VIDEO_AVC);
296 videoEncFormat_->Set<Tag::VIDEO_H264_PROFILE>(Plugins::VideoH264Profile::BASELINE);
297 videoEncFormat_->Set<Tag::VIDEO_H264_LEVEL>(32); // 32: LEVEL 3.2
298 }
299
ConfigureAudioDefaultEncFormat()300 void HiTransCoderImpl::ConfigureAudioDefaultEncFormat()
301 {
302 audioEncFormat_->GetData(Tag::MIME_TYPE, inputAudioMimeType_);
303 FALSE_RETURN_NOLOG(inputAudioMimeType_ != Plugins::MimeType::AUDIO_AAC);
304 MEDIA_LOG_I("Set the default audioEnc format, " PUBLIC_LOG_S " to " PUBLIC_LOG_S, inputAudioMimeType_.c_str(),
305 Plugins::MimeType::AUDIO_AAC);
306 audioEncFormat_->Set<Tag::MIME_TYPE>(Plugins::MimeType::AUDIO_AAC);
307 }
308
SetValueByType(const std::shared_ptr<Meta> & innerMeta,std::shared_ptr<Meta> & outputMeta)309 bool HiTransCoderImpl::SetValueByType(const std::shared_ptr<Meta> &innerMeta, std::shared_ptr<Meta> &outputMeta)
310 {
311 if (innerMeta == nullptr || outputMeta == nullptr) {
312 return false;
313 }
314 bool result = true;
315 for (const auto &metaKey : AVMETA_KEY) {
316 result &= ProcessMetaKey(innerMeta, outputMeta, metaKey);
317 }
318 return result;
319 }
320
ProcessMetaKey(const std::shared_ptr<Meta> & innerMeta,std::shared_ptr<Meta> & outputMeta,const std::string & metaKey)321 bool HiTransCoderImpl::ProcessMetaKey(
322 const std::shared_ptr<Meta> &innerMeta, std::shared_ptr<Meta> &outputMeta, const std::string &metaKey)
323 {
324 Any type = OHOS::Media::GetDefaultAnyValue(metaKey);
325 if (Any::IsSameTypeWith<int32_t>(type)) {
326 int32_t intVal;
327 if (innerMeta->GetData(metaKey, intVal)) {
328 outputMeta->SetData(metaKey, intVal);
329 }
330 } else if (Any::IsSameTypeWith<std::string>(type)) {
331 std::string strVal;
332 if (innerMeta->GetData(metaKey, strVal)) {
333 outputMeta->SetData(metaKey, strVal);
334 }
335 } else if (Any::IsSameTypeWith<Plugins::VideoRotation>(type)) {
336 Plugins::VideoRotation rotation;
337 if (innerMeta->GetData(metaKey, rotation)) {
338 outputMeta->SetData(metaKey, rotation);
339 }
340 } else if (Any::IsSameTypeWith<int64_t>(type)) {
341 int64_t duration;
342 if (innerMeta->GetData(metaKey, duration)) {
343 outputMeta->SetData(metaKey, duration);
344 }
345 } else if (Any::IsSameTypeWith<bool>(type)) {
346 bool isTrue;
347 if (innerMeta->GetData(metaKey, isTrue)) {
348 outputMeta->SetData(metaKey, isTrue);
349 }
350 } else if (Any::IsSameTypeWith<float>(type)) {
351 float value;
352 if (innerMeta->GetData(metaKey, value)) {
353 outputMeta->SetData(metaKey, value);
354 }
355 } else if (Any::IsSameTypeWith<double>(type)) {
356 double value;
357 if (innerMeta->GetData(metaKey, value)) {
358 outputMeta->SetData(metaKey, value);
359 }
360 } else if (Any::IsSameTypeWith<Plugins::AudioSampleFormat>(type)) {
361 Plugins::AudioSampleFormat value = Plugins::AudioSampleFormat::INVALID_WIDTH;
362 if (innerMeta->GetData(metaKey, value)) {
363 outputMeta->SetData(metaKey, value);
364 }
365 }
366 return true;
367 }
368
ConfigureVideoAudioMetaData()369 Status HiTransCoderImpl::ConfigureVideoAudioMetaData()
370 {
371 if (demuxerFilter_ == nullptr) {
372 MEDIA_LOG_E("demuxerFilter_ is nullptr");
373 return Status::ERROR_NULL_POINTER;
374 }
375 std::shared_ptr<Meta> globalInfo = demuxerFilter_->GetGlobalMetaInfo();
376 std::vector<std::shared_ptr<Meta>> trackInfos = demuxerFilter_->GetStreamMetaInfo();
377 size_t trackCount = trackInfos.size();
378 MEDIA_LOG_I("trackCount: %{public}d", trackCount);
379 if (trackCount == 0) {
380 MEDIA_LOG_E("No track found in the source");
381 CollectionErrorInfo(TransTranscoderStatus(Status::ERROR_NO_TRACK),
382 "ConfigureVideoAudioMetaData error");
383 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, MSERR_UNSUPPORT_VID_SRC_TYPE});
384 return Status::ERROR_NO_TRACK;
385 }
386 ConfigureMetaDataToTrackFormat(globalInfo, trackInfos);
387 ConfigureDefaultParameter();
388 return Status::OK;
389 }
390
SetOutputFile(const int32_t fd)391 int32_t HiTransCoderImpl::SetOutputFile(const int32_t fd)
392 {
393 MEDIA_LOG_I("HiTransCoderImpl::SetOutputFile()");
394 MEDIA_LOG_I("HiTransCoder SetOutputFile in, fd is %{public}d", fd);
395 fd_ = dup(fd);
396 MEDIA_LOG_I("HiTransCoder SetOutputFile dup, fd is %{public}d", fd_);
397 return MSERR_OK;
398 }
399
SetOutputFormat(OutputFormatType format)400 int32_t HiTransCoderImpl::SetOutputFormat(OutputFormatType format)
401 {
402 MEDIA_LOG_I("HiTransCoderImpl::SetOutputFormat(), OutputFormatType is %{public}d", static_cast<int32_t>(format));
403 outputFormatType_ = format;
404 return MSERR_OK;
405 }
406
SetObs(const std::weak_ptr<ITransCoderEngineObs> & obs)407 int32_t HiTransCoderImpl::SetObs(const std::weak_ptr<ITransCoderEngineObs> &obs)
408 {
409 MEDIA_LOG_I("HiTransCoderImpl::SetObs()");
410 obs_ = obs;
411 callbackLooper_->StartWithTransCoderEngineObs(obs);
412 return MSERR_OK;
413 }
414
ConfigureVideoEncoderFormat(const TransCoderParam & transCoderParam)415 void HiTransCoderImpl::ConfigureVideoEncoderFormat(const TransCoderParam &transCoderParam)
416 {
417 VideoEnc videoEnc = static_cast<const VideoEnc&>(transCoderParam);
418 MEDIA_LOG_I("HiTransCoderImpl::Configure videoEnc %{public}d", videoEnc.encFmt);
419 switch (videoEnc.encFmt) {
420 case OHOS::Media::VideoCodecFormat::H264:
421 videoEncFormat_->Set<Tag::MIME_TYPE>(Plugins::MimeType::VIDEO_AVC);
422 videoEncFormat_->Set<Tag::VIDEO_H264_PROFILE>(Plugins::VideoH264Profile::BASELINE);
423 videoEncFormat_->Set<Tag::VIDEO_H264_LEVEL>(32); // 32: LEVEL 3.2
424 break;
425 case OHOS::Media::VideoCodecFormat::MPEG4:
426 videoEncFormat_->Set<Tag::MIME_TYPE>(Plugins::MimeType::VIDEO_MPEG4);
427 break;
428 case OHOS::Media::VideoCodecFormat::H265:
429 videoEncFormat_->Set<Tag::MIME_TYPE>(Plugins::MimeType::VIDEO_HEVC);
430 break;
431 default:
432 break;
433 }
434 }
435
ConfigureVideoWidthHeight(const TransCoderParam & transCoderParam)436 void HiTransCoderImpl::ConfigureVideoWidthHeight(const TransCoderParam &transCoderParam)
437 {
438 VideoRectangle videoRectangle = static_cast<const VideoRectangle&>(transCoderParam);
439 if (videoRectangle.width != -1) {
440 videoEncFormat_->Set<Tag::VIDEO_WIDTH>(videoRectangle.width);
441 }
442 if (videoRectangle.height != -1) {
443 videoEncFormat_->Set<Tag::VIDEO_HEIGHT>(videoRectangle.height);
444 }
445 }
446
ConfigureColorSpace(const TransCoderParam & transCoderParam)447 Status HiTransCoderImpl::ConfigureColorSpace(const TransCoderParam &transCoderParam)
448 {
449 VideoColorSpace colSpa = static_cast<const VideoColorSpace&>(transCoderParam);
450 MEDIA_LOG_I("HiTranscoderImpl::ConfigureColorSpace %{public}d", static_cast<int32_t>(colSpa.colorSpaceFmt));
451 if (static_cast<int32_t>(colSpa.colorSpaceFmt) <= 0) {
452 return Status::ERROR_INVALID_PARAMETER;
453 }
454 videoEncFormat_->Set<Tag::AV_TRANSCODER_DST_COLOR_SPACE>(static_cast<int32_t>(colSpa.colorSpaceFmt));
455 return Status::OK;
456 }
457
ConfigureEnableBFrameEncoding(const TransCoderParam & transCoderParam)458 Status HiTransCoderImpl::ConfigureEnableBFrameEncoding(const TransCoderParam &transCoderParam)
459 {
460 VideoEnableBFrameEncoding enableBFrameEncoding = static_cast<const VideoEnableBFrameEncoding&>(transCoderParam);
461 MEDIA_LOG_I("HiTranscoderImpl::ConfigureEnableBFrameEncoding %{public}d", static_cast<int32_t>(
462 enableBFrameEncoding.enableBFrame));
463 videoEncFormat_->Set<Tag::AV_TRANSCODER_ENABLE_B_FRAME>(enableBFrameEncoding.enableBFrame);
464 return Status::OK;
465 }
466
ConfigureVideoBitrate()467 Status HiTransCoderImpl::ConfigureVideoBitrate()
468 {
469 int64_t videoBitrate = 0;
470 if (videoEncFormat_->Find(Tag::MEDIA_BITRATE) != videoEncFormat_->end()) {
471 videoEncFormat_->Get<Tag::MEDIA_BITRATE>(videoBitrate);
472 }
473 MEDIA_LOG_D("get videoBitrate: %{public}d", videoBitrate);
474 int32_t width = 0;
475 int32_t height = 0;
476 videoEncFormat_->GetData(Tag::VIDEO_WIDTH, width);
477 videoEncFormat_->GetData(Tag::VIDEO_HEIGHT, height);
478 const int32_t &minNum = std::min(width, height);
479 int32_t defaultVideoBitrate = videoBitrate;
480 if (minNum > HEIGHT_1080) {
481 defaultVideoBitrate = VIDEO_BITRATE_8M;
482 } else if (minNum > HEIGHT_720) {
483 defaultVideoBitrate = VIDEO_BITRATE_4M;
484 } else if (minNum > HEIGHT_480) {
485 defaultVideoBitrate = VIDEO_BITRATE_2M;
486 } else {
487 defaultVideoBitrate = VIDEO_BITRATE_1M;
488 }
489 MEDIA_LOG_D("set videoBitrate: %{public}d", defaultVideoBitrate);
490 videoEncFormat_->Set<Tag::MEDIA_BITRATE>(defaultVideoBitrate);
491 return Status::OK;
492 }
493
Configure(const TransCoderParam & transCoderParam)494 int32_t HiTransCoderImpl::Configure(const TransCoderParam &transCoderParam)
495 {
496 MEDIA_LOG_I("HiTransCoderImpl::Configure, type: " PUBLIC_LOG_U32, static_cast<uint32_t>(transCoderParam.type));
497 MediaTrace trace("HiTransCoderImpl::Configure()");
498 Status ret = ConfigureAudioParam(transCoderParam);
499 FALSE_RETURN_V_NOLOG(ret == Status::OK, TransTranscoderStatus(ret));
500 ret = ConfigureVideoParam(transCoderParam);
501 return TransTranscoderStatus(ret);
502 }
503
ConfigureVideoParam(const TransCoderParam & transCoderParam)504 Status HiTransCoderImpl::ConfigureVideoParam(const TransCoderParam &transCoderParam)
505 {
506 Status ret = Status::OK;
507 switch (transCoderParam.type) {
508 case TransCoderPublicParamType::VIDEO_ENC_FMT: {
509 ConfigureVideoEncoderFormat(transCoderParam);
510 break;
511 }
512 case TransCoderPublicParamType::VIDEO_RECTANGLE: {
513 ConfigureVideoWidthHeight(transCoderParam);
514 if (!isConfiguredVideoBitrate_) {
515 ConfigureVideoBitrate();
516 }
517 break;
518 }
519 case TransCoderPublicParamType::VIDEO_BITRATE: {
520 VideoBitRate videoBitrate = static_cast<const VideoBitRate&>(transCoderParam);
521 FALSE_RETURN_V_MSG(videoBitrate.bitRate > 0, Status::OK, "Invalid video bitrate");
522 MEDIA_LOG_I("HiTransCoderImpl::Configure videoBitRate %{public}d", videoBitrate.bitRate);
523 videoEncFormat_->Set<Tag::MEDIA_BITRATE>(videoBitrate.bitRate);
524 isConfiguredVideoBitrate_ = true;
525 break;
526 }
527 case TransCoderPublicParamType::COLOR_SPACE_FMT: {
528 ret = ConfigureColorSpace(transCoderParam);
529 break;
530 }
531 case TransCoderPublicParamType::VIDEO_ENABLE_B_FRAME_ENCODING: {
532 ret = ConfigureEnableBFrameEncoding(transCoderParam);
533 break;
534 }
535 default:
536 break;
537 }
538 return ret;
539 }
540
ConfigureAudioParam(const TransCoderParam & transCoderParam)541 Status HiTransCoderImpl::ConfigureAudioParam(const TransCoderParam &transCoderParam)
542 {
543 switch (transCoderParam.type) {
544 case TransCoderPublicParamType::AUDIO_ENC_FMT: {
545 AudioEnc audioEnc = static_cast<const AudioEnc&>(transCoderParam);
546 MEDIA_LOG_I("HiTransCoderImpl::Configure audioEnc %{public}d", audioEnc.encFmt);
547 if (inputAudioMimeType_ == Plugins::MimeType::AUDIO_AAC) {
548 skipProcessFilterFlag_.isSameAudioEncFmt = true;
549 }
550 audioEncFormat_->Set<Tag::MIME_TYPE>(Plugins::MimeType::AUDIO_AAC);
551 break;
552 }
553 case TransCoderPublicParamType::AUDIO_BITRATE: {
554 AudioBitRate audioBitrate = static_cast<const AudioBitRate&>(transCoderParam);
555 if (audioBitrate.bitRate <= 0) {
556 MEDIA_LOG_E("Invalid audioBitrate.bitRate %{public}d", audioBitrate.bitRate);
557 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, MSERR_PARAMETER_VERIFICATION_FAILED});
558 return Status::ERROR_INVALID_PARAMETER;
559 }
560 int64_t bitrate = -1;
561 audioEncFormat_->Get<Tag::MEDIA_BITRATE>(bitrate);
562 if (audioBitrate.bitRate == INVALID_AUDIO_BITRATE || audioBitrate.bitRate == bitrate) {
563 skipProcessFilterFlag_.isSameAudioBitrate = true;
564 }
565 audioBitrate.bitRate = audioBitrate.bitRate == INVALID_AUDIO_BITRATE ?
566 DEFAULT_AUDIO_BITRATE : audioBitrate.bitRate;
567 MEDIA_LOG_I("HiTransCoderImpl::Configure audioBitrate %{public}d", audioBitrate.bitRate);
568 audioEncFormat_->Set<Tag::MEDIA_BITRATE>(audioBitrate.bitRate);
569 break;
570 }
571 default:
572 break;
573 }
574 return Status::OK;
575 }
576
SkipAudioDecAndEnc()577 void HiTransCoderImpl::SkipAudioDecAndEnc()
578 {
579 FALSE_RETURN_NOLOG(demuxerFilter_ != nullptr);
580 (void)demuxerFilter_->SetSkippingAudioDecAndEnc();
581 }
582
Prepare()583 int32_t HiTransCoderImpl::Prepare()
584 {
585 MEDIA_LOG_I("HiTransCoderImpl::Prepare()");
586 MediaTrace trace("HiTransCoderImpl::Prepare()");
587 int32_t width = 0;
588 int32_t height = 0;
589 if (isExistVideoTrack_) {
590 if (videoEncFormat_->GetData(Tag::VIDEO_WIDTH, width) &&
591 videoEncFormat_->GetData(Tag::VIDEO_HEIGHT, height)) {
592 MEDIA_LOG_D("set output video width: %{public}d, height: %{public}d", width, height);
593 } else {
594 MEDIA_LOG_E("Output video width or height not set");
595 CollectionErrorInfo(MSERR_INVALID_VAL, "Prepare error");
596 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, MSERR_INVALID_VAL});
597 return MSERR_INVALID_VAL;
598 }
599 if (width > inputVideoWidth_ || height > inputVideoHeight_ || std::min(width, height) < MINIMUM_WIDTH_HEIGHT) {
600 MEDIA_LOG_E("Output video width or height is invalid");
601 CollectionErrorInfo(MSERR_PARAMETER_VERIFICATION_FAILED, "Prepare error");
602 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, MSERR_PARAMETER_VERIFICATION_FAILED});
603 return MSERR_PARAMETER_VERIFICATION_FAILED;
604 }
605 skipProcessFilterFlag_.isSameVideoResolution = (width == inputVideoWidth_) && (height == inputVideoHeight_);
606 }
607 if (skipProcessFilterFlag_.CanSkipAudioDecAndEncFilter()) {
608 SkipAudioDecAndEnc();
609 }
610 Status ret = pipeline_->Prepare();
611 if (ret != Status::OK) {
612 MEDIA_LOG_E("Prepare failed with error " PUBLIC_LOG_D32, ret);
613 auto errCode = TransTranscoderStatus(ret);
614 CollectionErrorInfo(errCode, "Prepare error");
615 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, errCode});
616 return errCode;
617 }
618 Status errCode = SetSurfacePipeline(width, height);
619 if (errCode == Status::ERROR_UNKNOWN) {
620 errCode = Status::ERROR_SET_OUTPUT_SURFACE_FAILED;
621 }
622 return TransTranscoderStatus(errCode);
623 }
624
SetSurfacePipeline(int32_t outputVideoWidth,int32_t outputVideoHeight)625 Status HiTransCoderImpl::SetSurfacePipeline(int32_t outputVideoWidth, int32_t outputVideoHeight)
626 {
627 FALSE_RETURN_V_MSG_E(videoEncoderFilter_ != nullptr && videoDecoderFilter_ != nullptr,
628 Status::ERROR_NULL_POINTER, "VideoDecoder setOutputSurface failed");
629 if (!skipProcessFilterFlag_.CanSkipVideoResizeFilter() && videoResizeFilter_ != nullptr) {
630 sptr<Surface> resizeFilterSurface = videoResizeFilter_->GetInputSurface();
631 FALSE_RETURN_V_MSG_E(resizeFilterSurface != nullptr, Status::ERROR_GET_INPUT_SURFACE_FAILED,
632 "resizeFilterSurface is nullptr");
633 Status ret = videoDecoderFilter_->SetOutputSurface(resizeFilterSurface);
634 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "VideoDecoder setOutputSurface failed");
635 sptr<Surface> encoderFilterSurface = videoEncoderFilter_->GetInputSurface();
636 FALSE_RETURN_V_MSG_E(encoderFilterSurface != nullptr, Status::ERROR_GET_INPUT_SURFACE_FAILED,
637 "encoderFilterSurface is nullptr");
638 return videoResizeFilter_->SetOutputSurface(encoderFilterSurface, outputVideoWidth, outputVideoHeight);
639 }
640 sptr<Surface> encoderFilterSurface = videoEncoderFilter_->GetInputSurface();
641 FALSE_RETURN_V_MSG_E(encoderFilterSurface != nullptr, Status::ERROR_GET_INPUT_SURFACE_FAILED,
642 "encoderFilterSurface is nullptr");
643 return videoDecoderFilter_->SetOutputSurface(encoderFilterSurface);
644 }
645
Start()646 int32_t HiTransCoderImpl::Start()
647 {
648 MEDIA_LOG_I("HiTransCoderImpl::Start()");
649 MediaTrace trace("HiTransCoderImpl::Start()");
650 startTime_ = GetCurrentMillisecond();
651 int32_t ret = TransTranscoderStatus(pipeline_->Start());
652 if (ret != MSERR_OK) {
653 MEDIA_LOG_E("Start pipeline failed");
654 CollectionErrorInfo(ret, "Start error");
655 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, ret});
656 return ret;
657 }
658 callbackLooper_->StartReportMediaProgress(REPORT_PROGRESS_INTERVAL);
659 return MSERR_OK;
660 }
661
Pause()662 int32_t HiTransCoderImpl::Pause()
663 {
664 MEDIA_LOG_I("HiTransCoderImpl::Pause()");
665 MediaTrace trace("HiTransCoderImpl::Pause()");
666 callbackLooper_->StopReportMediaProgress();
667 int32_t ret = TransTranscoderStatus(pipeline_->Pause());
668 if (ret != MSERR_OK) {
669 MEDIA_LOG_E("Pause pipeline failed");
670 CollectionErrorInfo(ret, "Pause error");
671 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, ret});
672 }
673 if (startTime_ != -1) {
674 transcoderTotalDuration_ += GetCurrentMillisecond() - startTime_;
675 }
676 startTime_ = -1;
677 return ret;
678 }
679
Resume()680 int32_t HiTransCoderImpl::Resume()
681 {
682 MEDIA_LOG_I("HiTransCoderImpl::Resume()");
683 MediaTrace trace("HiTransCoderImpl::Resume()");
684 int32_t ret = TransTranscoderStatus(pipeline_->Resume());
685 if (ret != MSERR_OK) {
686 MEDIA_LOG_E("Resume pipeline failed");
687 CollectionErrorInfo(ret, "Resume error");
688 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, ret});
689 return ret;
690 }
691 callbackLooper_->StartReportMediaProgress(REPORT_PROGRESS_INTERVAL);
692 startTime_ = GetCurrentMillisecond();
693 return MSERR_OK;
694 }
695
Cancel()696 int32_t HiTransCoderImpl::Cancel()
697 {
698 MEDIA_LOG_I("HiTransCoderImpl::Cancel enter");
699 MediaTrace trace("HiTransCoderImpl::Cancel()");
700 callbackLooper_->StopReportMediaProgress();
701 int32_t ret = TransTranscoderStatus(pipeline_->Stop());
702 callbackLooper_->Stop();
703 if (ret != MSERR_OK) {
704 MEDIA_LOG_E("Stop pipeline failed");
705 CollectionErrorInfo(ret, "Cancel error");
706 OnEvent({"TranscoderEngine", EventType::EVENT_ERROR, ret});
707 return ret;
708 }
709 MEDIA_LOG_I("HiTransCoderImpl::Cancel done");
710 if (startTime_ != -1) {
711 transcoderTotalDuration_ += GetCurrentMillisecond() - startTime_;
712 }
713 startTime_ = -1;
714 AppendTranscoderMediaInfo();
715 ReportMediaInfo(instanceId_);
716 return MSERR_OK;
717 }
718
AppendTranscoderMediaInfo()719 void HiTransCoderImpl::AppendTranscoderMediaInfo()
720 {
721 MEDIA_LOG_I("HiTransCoderImplAppendTranscoderMediaInfo");
722
723 std::shared_ptr<Meta> meta = std::make_shared<Meta>();
724 meta->SetData(Tag::AV_TRANSCODER_ERR_CODE, errCode_);
725 meta->SetData(Tag::AV_TRANSCODER_ERR_MSG, errMsg_);
726 meta->SetData(Tag::AV_TRANSCODER_SOURCE_DURATION, durationMs_.load());
727 meta->SetData(Tag::AV_TRANSCODER_TRANSCODER_DURATION, static_cast<int32_t>(transcoderTotalDuration_));
728
729 AppendSrcMediaInfo(meta);
730 AppendDstMediaInfo(meta);
731 AppendMediaInfo(meta, instanceId_);
732 }
733
AppendSrcMediaInfo(std::shared_ptr<Meta> meta)734 void HiTransCoderImpl::AppendSrcMediaInfo(std::shared_ptr<Meta> meta)
735 {
736 FALSE_RETURN_MSG(meta != nullptr, "meta is invalid.");
737 std::string srcAudioMime;
738 srcAudioFormat_->Get<Tag::MIME_TYPE>(srcAudioMime);
739 meta->SetData(Tag::AV_TRANSCODER_SRC_AUDIO_MIME, srcAudioMime);
740 std::string srcVideoMime;
741 srcVideoFormat_->Get<Tag::MIME_TYPE>(srcVideoMime);
742 meta->SetData(Tag::AV_TRANSCODER_SRC_VIDEO_MIME, srcVideoMime);
743
744 int64_t srcVideoBitrate;
745 srcVideoFormat_->Get<Tag::MEDIA_BITRATE>(srcVideoBitrate);
746 meta->SetData(Tag::AV_TRANSCODER_SRC_VIDEO_BITRATE, static_cast<int32_t>(srcVideoBitrate));
747
748 bool isHdrVivid;
749 srcVideoFormat_->Get<Tag::VIDEO_IS_HDR_VIVID>(isHdrVivid);
750 if (isHdrVivid) {
751 meta->SetData(Tag::AV_TRANSCODER_SRC_HDR_TYPE, 1);
752 } else {
753 meta->SetData(Tag::AV_TRANSCODER_SRC_HDR_TYPE, 0);
754 }
755 int32_t srcAudioSampleRate;
756 srcAudioFormat_->Get<Tag::AUDIO_SAMPLE_RATE>(srcAudioSampleRate);
757 meta->SetData(Tag::AV_TRANSCODER_SRC_AUDIO_SAMPLE_RATE, srcAudioSampleRate);
758 int32_t srcAudiohannels;
759 srcAudioFormat_->Get<Tag::AUDIO_CHANNEL_COUNT>(srcAudiohannels);
760 meta->SetData(Tag::AV_TRANSCODER_SRC_AUDIO_CHANNEL_COUNT, srcAudiohannels);
761 int64_t srcAudioBitrate;
762 srcAudioFormat_->Get<Tag::MEDIA_BITRATE>(srcAudioBitrate);
763 meta->SetData(Tag::AV_TRANSCODER_SRC_AUDIO_BITRATE, static_cast<int32_t>(srcAudioBitrate));
764 }
765
AppendDstMediaInfo(std::shared_ptr<Meta> meta)766 void HiTransCoderImpl::AppendDstMediaInfo(std::shared_ptr<Meta> meta)
767 {
768 FALSE_RETURN_MSG(meta != nullptr, "meta is invalid.");
769 std::string dstAudioMime;
770 audioEncFormat_->Get<Tag::MIME_TYPE>(dstAudioMime);
771 meta->SetData(Tag::AV_TRANSCODER_DST_AUDIO_MIME, dstAudioMime);
772 std::string dstVideoMime;
773 videoEncFormat_->Get<Tag::MIME_TYPE>(dstVideoMime);
774 meta->SetData(Tag::AV_TRANSCODER_DST_VIDEO_MIME, dstVideoMime);
775 int64_t dstVideoBitrate;
776 videoEncFormat_->Get<Tag::MEDIA_BITRATE>(dstVideoBitrate);
777 meta->SetData(Tag::AV_TRANSCODER_DST_VIDEO_BITRATE, static_cast<int32_t>(dstVideoBitrate));
778 meta->SetData(Tag::AV_TRANSCODER_DST_HDR_TYPE, 0);
779 int32_t colorSpaceFormat = 0;
780 videoEncFormat_->Get<Tag::AV_TRANSCODER_DST_COLOR_SPACE>(colorSpaceFormat);
781 meta->SetData(Tag::AV_TRANSCODER_DST_COLOR_SPACE, colorSpaceFormat);
782 bool enableBFrame = false;
783 videoEncFormat_->Get<Tag::AV_TRANSCODER_ENABLE_B_FRAME>(enableBFrame);
784 meta->SetData(Tag::VIDEO_ENCODER_ENABLE_B_FRAME, enableBFrame);
785 int32_t dstAudioSampleRate;
786 audioEncFormat_->Get<Tag::AUDIO_SAMPLE_RATE>(dstAudioSampleRate);
787 meta->SetData(Tag::AV_TRANSCODER_DST_AUDIO_SAMPLE_RATE, dstAudioSampleRate);
788 int32_t dstAudiohannels;
789 audioEncFormat_->Get<Tag::AUDIO_CHANNEL_COUNT>(dstAudiohannels);
790 meta->SetData(Tag::AV_TRANSCODER_DST_AUDIO_CHANNEL_COUNT, dstAudiohannels);
791 int64_t dstAudioBitrate;
792 audioEncFormat_->Get<Tag::MEDIA_BITRATE>(dstAudioBitrate);
793 meta->SetData(Tag::AV_TRANSCODER_DST_AUDIO_BITRATE, static_cast<int32_t>(dstAudioBitrate));
794 }
795
OnEvent(const Event & event)796 void HiTransCoderImpl::OnEvent(const Event &event)
797 {
798 switch (event.type) {
799 case EventType::EVENT_ERROR: {
800 HandleErrorEvent(AnyCast<int32_t>(event.param));
801 break;
802 }
803 case EventType::EVENT_COMPLETE: {
804 MEDIA_LOG_I("HiTransCoderImpl EVENT_COMPLETE");
805 HandleCompleteEvent();
806 break;
807 }
808 default:
809 break;
810 }
811 }
812
HandleErrorEvent(int32_t errorCode)813 void HiTransCoderImpl::HandleErrorEvent(int32_t errorCode)
814 {
815 {
816 std::unique_lock<std::mutex> lock(ignoreErrorMutex_);
817 FALSE_RETURN_MSG(!ignoreError_, "igore this error event!");
818 ignoreError_ = true;
819 }
820 MEDIA_LOG_W("OnError, errorCode: " PUBLIC_LOG_D32, errorCode);
821 FALSE_RETURN_MSG(callbackLooper_ != nullptr, "callbackLooper is nullptr");
822 callbackLooper_->StopReportMediaProgress();
823 if (pipeline_ != nullptr) {
824 pipeline_->Pause();
825 }
826 callbackLooper_->OnError(TRANSCODER_ERROR_INTERNAL, errorCode);
827 }
828
HandleCompleteEvent()829 void HiTransCoderImpl::HandleCompleteEvent()
830 {
831 FALSE_RETURN_MSG(callbackLooper_ != nullptr, "callbackLooper is nullptr");
832 callbackLooper_->StopReportMediaProgress();
833 auto ptr = obs_.lock();
834 if (ptr != nullptr) {
835 ptr->OnInfo(TransCoderOnInfoType::INFO_TYPE_PROGRESS_UPDATE, TRANSCODER_COMPLETE_PROGRESS);
836 ptr->OnInfo(TransCoderOnInfoType::INFO_TYPE_TRANSCODER_COMPLETED, 0);
837 }
838 if (pipeline_ != nullptr) {
839 MEDIA_LOG_I("complete, stop in");
840 int32_t ret = TransTranscoderStatus(pipeline_->Stop());
841 MEDIA_LOG_I("complete, stop out, ret: " PUBLIC_LOG_D32, ret);
842 }
843 callbackLooper_->Stop();
844 }
845
LinkAudioDecoderFilter(const std::shared_ptr<Pipeline::Filter> & preFilter,Pipeline::StreamType type)846 Status HiTransCoderImpl::LinkAudioDecoderFilter(const std::shared_ptr<Pipeline::Filter>& preFilter,
847 Pipeline::StreamType type)
848 {
849 MEDIA_LOG_I("HiTransCoderImpl::LinkAudioDecoderFilter()");
850 audioDecoderFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::AudioDecoderFilter>(
851 "audioDecoderFilter", Pipeline::FilterType::FILTERTYPE_ADEC);
852 FALSE_RETURN_V_MSG_E(audioDecoderFilter_ != nullptr, Status::ERROR_NULL_POINTER,
853 "audioDecoderFilter is nullptr");
854 audioDecoderFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
855 Status ret = pipeline_->LinkFilters(preFilter, {audioDecoderFilter_}, type);
856 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Add audioDecoderFilter to pipeline fail");
857 return Status::OK;
858 }
859
LinkAudioEncoderFilter(const std::shared_ptr<Pipeline::Filter> & preFilter,Pipeline::StreamType type)860 Status HiTransCoderImpl::LinkAudioEncoderFilter(const std::shared_ptr<Pipeline::Filter>& preFilter,
861 Pipeline::StreamType type)
862 {
863 MEDIA_LOG_I("HiTransCoderImpl::LinkAudioEncoderFilter()");
864 audioEncoderFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::AudioEncoderFilter>
865 ("audioEncoderFilter", Pipeline::FilterType::FILTERTYPE_AENC);
866 FALSE_RETURN_V_MSG_E(audioEncoderFilter_ != nullptr, Status::ERROR_NULL_POINTER,
867 "audioEncoderFilter is nullptr");
868 audioEncFormat_->Set<Tag::APP_TOKEN_ID>(appTokenId_);
869 audioEncFormat_->Set<Tag::APP_UID>(appUid_);
870 audioEncFormat_->Set<Tag::APP_PID>(appPid_);
871 audioEncFormat_->Set<Tag::APP_FULL_TOKEN_ID>(appFullTokenId_);
872 audioEncFormat_->Set<Tag::AUDIO_ENCODE_PTS_MODE>(GENERATE_ENCODE_PTS_BY_INPUT_MODE);
873 Status ret = audioEncoderFilter_->SetCodecFormat(audioEncFormat_);
874 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "audioEncoderFilter SetCodecFormat fail");
875 ret = audioEncoderFilter_->SetTranscoderMode();
876 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "audioEncoderFilter SetTranscoderMode fail");
877 audioEncoderFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
878 ret = audioEncoderFilter_->Configure(audioEncFormat_);
879 if (ret == Status::ERROR_UNKNOWN) {
880 ret = Status::ERROR_AUD_ENC_FAILED;
881 }
882 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "audioEncoderFilter Configure fail");
883 ret = pipeline_->LinkFilters(preFilter, {audioEncoderFilter_}, type);
884 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Add audioEncoderFilter to pipeline fail");
885 return Status::OK;
886 }
887
LinkVideoDecoderFilter(const std::shared_ptr<Pipeline::Filter> & preFilter,Pipeline::StreamType type)888 Status HiTransCoderImpl::LinkVideoDecoderFilter(const std::shared_ptr<Pipeline::Filter>& preFilter,
889 Pipeline::StreamType type)
890 {
891 MEDIA_LOG_I("HiTransCoderImpl::LinkVideoDecoderFilter()");
892 videoDecoderFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::SurfaceDecoderFilter>(
893 "surfacedecoder", Pipeline::FilterType::FILTERTYPE_VIDEODEC);
894 FALSE_RETURN_V_MSG_E(videoDecoderFilter_ != nullptr, Status::ERROR_NULL_POINTER,
895 "videoDecoderFilter is nullptr");
896 videoDecoderFilter_->SetCodecFormat(videoEncFormat_);
897 videoDecoderFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
898 Status ret = pipeline_->LinkFilters(preFilter, {videoDecoderFilter_}, type);
899 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Add videoDecoderFilter to pipeline failed");
900 return Status::OK;
901 }
902
LinkVideoEncoderFilter(const std::shared_ptr<Pipeline::Filter> & preFilter,Pipeline::StreamType type)903 Status HiTransCoderImpl::LinkVideoEncoderFilter(const std::shared_ptr<Pipeline::Filter>& preFilter,
904 Pipeline::StreamType type)
905 {
906 MEDIA_LOG_I("HiTransCoderImpl::LinkVideoEncoderFilter()");
907 videoEncoderFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::SurfaceEncoderFilter>
908 ("videoEncoderFilter", Pipeline::FilterType::FILTERTYPE_VENC);
909 FALSE_RETURN_V_MSG_E(videoEncoderFilter_ != nullptr, Status::ERROR_NULL_POINTER,
910 "videoEncoderFilter is nullptr");
911 FALSE_RETURN_V_MSG_E(videoEncFormat_ != nullptr, Status::ERROR_NULL_POINTER,
912 "videoEncFormat is nullptr");
913 videoEncFormat_->Set<Tag::VIDEO_ENCODE_BITRATE_MODE>(Plugins::VideoEncodeBitrateMode::VBR);
914 Status ret = videoEncoderFilter_->SetCodecFormat(videoEncFormat_);
915 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "videoEncoderFilter SetCodecFormat fail");
916 videoEncoderFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
917 ret = videoEncoderFilter_->SetTransCoderMode();
918 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "videoEncoderFilter SetTransCoderMode fail");
919 ret = videoEncoderFilter_->Configure(videoEncFormat_);
920 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "videoEncoderFilter Configure fail");
921 ret = pipeline_->LinkFilters(preFilter, {videoEncoderFilter_}, type);
922 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Add videoEncoderFilter to pipeline fail");
923 return Status::OK;
924 }
925
LinkVideoResizeFilter(const std::shared_ptr<Pipeline::Filter> & preFilter,Pipeline::StreamType type)926 Status HiTransCoderImpl::LinkVideoResizeFilter(const std::shared_ptr<Pipeline::Filter>& preFilter,
927 Pipeline::StreamType type)
928 {
929 MEDIA_LOG_I("HiTransCoderImpl::LinkVideoResizeFilter()");
930 videoResizeFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::VideoResizeFilter>
931 ("videoResizeFilter", Pipeline::FilterType::FILTERTYPE_VIDRESIZE);
932 FALSE_RETURN_V_MSG_E(videoResizeFilter_ != nullptr, Status::ERROR_NULL_POINTER,
933 "videoResizeFilter_ is nullptr");
934 videoResizeFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
935 Status ret = videoResizeFilter_->Configure(videoEncFormat_);
936 if (ret == Status::ERROR_UNKNOWN) {
937 ret = Status::ERROR_VID_RESIZE_FAILED;
938 }
939 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "videoEncoderFilter Configure fail");
940 ret = pipeline_->LinkFilters(preFilter, {videoResizeFilter_}, type);
941 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Add videoResizeFilter to pipeline fail");
942 return Status::OK;
943 }
944
LinkMuxerFilter(const std::shared_ptr<Pipeline::Filter> & preFilter,Pipeline::StreamType type)945 Status HiTransCoderImpl::LinkMuxerFilter(const std::shared_ptr<Pipeline::Filter>& preFilter,
946 Pipeline::StreamType type)
947 {
948 MEDIA_LOG_I("HiTransCoderImpl::LinkMuxerFilter()");
949 Status ret = Status::OK;
950 if (muxerFilter_ == nullptr) {
951 muxerFilter_ = Pipeline::FilterFactory::Instance().CreateFilter<Pipeline::MuxerFilter>
952 ("muxerFilter", Pipeline::FilterType::FILTERTYPE_MUXER);
953 FALSE_RETURN_V_MSG_E(muxerFilter_ != nullptr, Status::ERROR_NULL_POINTER,
954 "muxerFilter is nullptr");
955 muxerFilter_->Init(transCoderEventReceiver_, transCoderFilterCallback_);
956 ret = muxerFilter_->SetOutputParameter(appUid_, appPid_, fd_, outputFormatType_);
957 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "muxerFilter SetOutputParameter fail");
958 muxerFilter_->SetParameter(muxerFormat_);
959 muxerFilter_->SetTransCoderMode();
960 MEDIA_LOG_I("HiTransCoder CloseFd, fd is %{public}d", fd_);
961 if (fd_ >= 0) {
962 (void)::close(fd_);
963 fd_ = -1;
964 }
965 }
966 ret = pipeline_->LinkFilters(preFilter, {muxerFilter_}, type);
967 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Add muxerFilter to pipeline fail");
968 return Status::OK;
969 }
970
OnCallback(std::shared_ptr<Pipeline::Filter> filter,const Pipeline::FilterCallBackCommand cmd,Pipeline::StreamType outType)971 Status HiTransCoderImpl::OnCallback(std::shared_ptr<Pipeline::Filter> filter, const Pipeline::FilterCallBackCommand cmd,
972 Pipeline::StreamType outType)
973 {
974 MEDIA_LOG_I("HiPlayerImpl::OnCallback filter, outType: %{public}d", static_cast<int32_t>(outType));
975 FALSE_RETURN_V_MSG_E(filter != nullptr, Status::ERROR_NULL_POINTER, "filter is nullptr");
976 if (cmd == Pipeline::FilterCallBackCommand::NEXT_FILTER_NEEDED) {
977 switch (outType) {
978 case Pipeline::StreamType::STREAMTYPE_RAW_AUDIO:
979 if (filter->GetFilterType() == Pipeline::FilterType::FILTERTYPE_DEMUXER) {
980 FALSE_RETURN_V(!isAudioTrackLinked_, Status::OK);
981 isAudioTrackLinked_ = true;
982 }
983 return LinkAudioEncoderFilter(filter, outType);
984 case Pipeline::StreamType::STREAMTYPE_ENCODED_AUDIO:
985 if (filter->GetFilterType() == Pipeline::FilterType::FILTERTYPE_DEMUXER) {
986 FALSE_RETURN_V(!isAudioTrackLinked_, Status::OK);
987 isAudioTrackLinked_ = true;
988 FALSE_RETURN_V_NOLOG(skipProcessFilterFlag_.CanSkipAudioDecAndEncFilter(),
989 LinkAudioDecoderFilter(filter, outType));
990 }
991 return LinkMuxerFilter(filter, outType);
992 case Pipeline::StreamType::STREAMTYPE_RAW_VIDEO:
993 if (skipProcessFilterFlag_.CanSkipVideoResizeFilter() ||
994 filter->GetFilterType() == Pipeline::FilterType::FILTERTYPE_VIDRESIZE) {
995 return LinkVideoEncoderFilter(filter, outType);
996 }
997 return LinkVideoResizeFilter(filter, outType);
998 case Pipeline::StreamType::STREAMTYPE_ENCODED_VIDEO:
999 if (filter->GetFilterType() == Pipeline::FilterType::FILTERTYPE_DEMUXER) {
1000 FALSE_RETURN_V(!isVideoTrackLinked_, Status::OK);
1001 isVideoTrackLinked_ = true;
1002 return LinkVideoDecoderFilter(filter, outType);
1003 }
1004 return LinkMuxerFilter(filter, outType);
1005 default:
1006 break;
1007 }
1008 }
1009 return Status::OK;
1010 }
1011
GetCurrentTime(int32_t & currentPositionMs)1012 int32_t HiTransCoderImpl::GetCurrentTime(int32_t& currentPositionMs)
1013 {
1014 FALSE_RETURN_V(muxerFilter_ != nullptr, MSERR_UNKNOWN);
1015 int64_t currentPts = muxerFilter_->GetCurrentPtsMs();
1016 currentPositionMs = (int32_t)currentPts;
1017 return MSERR_OK;
1018 }
1019
GetDuration(int32_t & durationMs)1020 int32_t HiTransCoderImpl::GetDuration(int32_t& durationMs)
1021 {
1022 durationMs = durationMs_.load();
1023 return MSERR_OK;
1024 }
1025
GetCurrentMillisecond()1026 int64_t HiTransCoderImpl::GetCurrentMillisecond()
1027 {
1028 std::chrono::system_clock::duration duration = std::chrono::system_clock::now().time_since_epoch();
1029 int64_t time = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
1030 return time;
1031 }
1032
CollectionErrorInfo(int32_t errCode,const std::string & errMsg)1033 void HiTransCoderImpl::CollectionErrorInfo(int32_t errCode, const std::string& errMsg)
1034 {
1035 MEDIA_LOG_E_SHORT("Error: " PUBLIC_LOG_S, errMsg.c_str());
1036 errCode_ = errCode;
1037 errMsg_ = errMsg;
1038 }
1039 } // namespace MEDIA
1040 } // namespace OHOS
1041