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