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