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