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