1 /*
2 * Copyright (c) 2024-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
16 #include "muxer.h"
17
18 #include "basic_definitions.h"
19 #include "dp_log.h"
20
21 namespace OHOS {
22 namespace CameraStandard {
23 namespace DeferredProcessing {
~Muxer()24 Muxer::~Muxer()
25 {
26 DP_DEBUG_LOG("entered.");
27 muxer_ = nullptr;
28 }
29
Create(int32_t outputFd,Plugins::OutputFormat format)30 MediaManagerError Muxer::Create(int32_t outputFd, Plugins::OutputFormat format)
31 {
32 DP_DEBUG_LOG("entered.");
33 DP_CHECK_ERROR_RETURN_RET_LOG(outputFd == INVALID_FD, ERROR_FAIL, "outputFd is invalid: %{public}d.", outputFd);
34
35 muxer_ = AVMuxerFactory::CreateAVMuxer(outputFd, format);
36 DP_CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, ERROR_FAIL, "Create avmuxer failed.");
37
38 return OK;
39 }
40
AddTracks(const std::map<Media::Plugins::MediaType,std::shared_ptr<Track>> & trackMap)41 MediaManagerError Muxer::AddTracks(const std::map<Media::Plugins::MediaType, std::shared_ptr<Track>>& trackMap)
42 {
43 DP_DEBUG_LOG("entered.");
44 DP_CHECK_ERROR_RETURN_RET_LOG(trackMap.empty(), ERROR_FAIL, "Invalid track map: trackMap is empty.");
45
46 for (const auto& trackType : trackList_) {
47 auto it = trackMap.find(trackType);
48 DP_CHECK_ERROR_RETURN_RET_LOG(it == trackMap.end() && trackType != Media::Plugins::MediaType::TIMEDMETA,
49 ERROR_FAIL, "Not find trackType: %{public}d.", trackType);
50
51 const auto track = it != trackMap.end() ? it->second : nullptr;
52 if (trackType == Media::Plugins::MediaType::TIMEDMETA) {
53 auto ret = CheckAndAddMetaTrack(track);
54 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
55 "Failed to add track: %{public}d, ret: %{public}d.", trackType, ret);
56 continue;
57 }
58
59 auto ret = muxer_->AddTrack(trackIds_[trackType], track->GetFormat().format->GetMeta());
60 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
61 "Failed to add track: %{public}d, ret: %{public}d.", trackType, ret);
62 }
63 return OK;
64 }
65
CheckAndAddMetaTrack(const std::shared_ptr<Track> & track)66 MediaManagerError Muxer::CheckAndAddMetaTrack(const std::shared_ptr<Track>& track)
67 {
68 std::shared_ptr<Meta> meta = nullptr;
69 if (track == nullptr) {
70 meta = std::make_shared<Meta>();
71 meta->Set<Tag::MIME_TYPE>(MIME_TIMED_META);
72 meta->Set<Tag::TIMED_METADATA_KEY>(TIMED_METADATA_VALUE);
73 } else {
74 meta = track->GetFormat().format->GetMeta();
75 }
76 meta->Set<Tag::TIMED_METADATA_SRC_TRACK>(trackIds_[Media::Plugins::MediaType::VIDEO]);
77 auto ret = muxer_->AddTrack(trackIds_[Media::Plugins::MediaType::TIMEDMETA], meta);
78 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
79 "Failed to add track: %{public}d, ret: %{public}d.", Media::Plugins::MediaType::TIMEDMETA, ret);
80 return OK;
81 }
82
83
WriteStream(Media::Plugins::MediaType trackType,const std::shared_ptr<AVBuffer> & sample)84 MediaManagerError Muxer::WriteStream(Media::Plugins::MediaType trackType, const std::shared_ptr<AVBuffer>& sample)
85 {
86 int32_t trackId = GetTrackId(trackType);
87 DP_CHECK_ERROR_RETURN_RET_LOG(trackId == INVALID_TRACK_ID, ERROR_FAIL, "Invalid track id.");
88
89 auto ret = muxer_->WriteSample(trackId, sample);
90 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
91 "Write sample failed, ret: %{public}d.", ret);
92
93 return OK;
94 }
95
GetTrackId(Media::Plugins::MediaType trackType)96 int32_t Muxer::GetTrackId(Media::Plugins::MediaType trackType)
97 {
98 auto it = trackIds_.find(trackType);
99 return (it != trackIds_.end()) ? it->second : INVALID_TRACK_ID;
100 }
101
Start()102 MediaManagerError Muxer::Start()
103 {
104 DP_DEBUG_LOG("entered.");
105 auto ret = muxer_->Start();
106 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
107 "Failed to start, ret: %{public}d", ret);
108
109 return OK;
110 }
111
Stop()112 MediaManagerError Muxer::Stop()
113 {
114 DP_DEBUG_LOG("entered.");
115 auto ret = muxer_->Stop();
116 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "Failed to stop, ret: %{public}d", ret);
117
118 return OK;
119 }
AddMediaInfo(const std::shared_ptr<MediaInfo> & mediaInfo)120 MediaManagerError Muxer::AddMediaInfo(const std::shared_ptr<MediaInfo>& mediaInfo)
121 {
122 auto param = std::make_shared<Meta>();
123 int32_t rotation = mediaInfo->codecInfo.rotation == -1 ? 0 : mediaInfo->codecInfo.rotation;
124 param->Set<Tag::VIDEO_ROTATION>(static_cast<Plugins::VideoRotation>(rotation));
125 param->Set<Tag::MEDIA_CREATION_TIME>(mediaInfo->creationTime);
126 param->Set<Tag::VIDEO_IS_HDR_VIVID>(mediaInfo->codecInfo.isHdrvivid);
127 if (mediaInfo->latitude > 0) {
128 param->Set<Tag::MEDIA_LATITUDE>(mediaInfo->latitude);
129 }
130 if (mediaInfo->longitude > 0) {
131 param->Set<Tag::MEDIA_LONGITUDE>(mediaInfo->longitude);
132 }
133 auto ret = muxer_->SetParameter(param);
134 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
135 "Add param failed, ret: %{public}d", ret);
136
137 if (mediaInfo->livePhotoCovertime > 0) {
138 auto userMeta = std::make_shared<Meta>();
139 userMeta->SetData(LIVE_PHOTO_COVERTIME, mediaInfo->livePhotoCovertime);
140 ret = muxer_->SetUserMeta(userMeta);
141 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
142 "Add userMeta failed, ret: %{public}d", ret);
143 }
144
145 return OK;
146 }
147
AddUserMeta(const std::shared_ptr<Meta> & userMeta)148 MediaManagerError Muxer::AddUserMeta(const std::shared_ptr<Meta>& userMeta)
149 {
150 auto ret = muxer_->SetUserMeta(userMeta);
151 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
152 "Add user meta failed, ret: %{public}d", ret);
153
154 return OK;
155 }
156 } // namespace DeferredProcessing
157 } // namespace CameraStandard
158 } // namespace OHOS
159