• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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