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 "dash_period_manager.h"
17 #include "dash_manager_util.h"
18
19 namespace OHOS {
20 namespace Media {
21 namespace Plugins {
22 namespace HttpPlugin {
23 /**
24 * @brief ContentComponent contain mime type such as audio/application
25 *
26 * @param contentComp contentcomponent list
27 * @param pattern audio/application
28 *
29 * @return bool
30 */
ContainType(DashList<DashContentCompInfo * > contentComp,const std::string & pattern)31 static bool ContainType(DashList<DashContentCompInfo *> contentComp, const std::string &pattern)
32 {
33 bool flag = false;
34 for (DashList<DashContentCompInfo *>::iterator it = contentComp.begin(); it != contentComp.end(); ++it) {
35 std::string type((*it)->contentType_);
36 if (!type.empty() && type == pattern) {
37 flag = true;
38 break;
39 }
40 }
41
42 return flag;
43 }
44
GetMimeTypeFromRepresentation(const DashAdptSetInfo * adptSetInfo,std::string & mimeType)45 static void GetMimeTypeFromRepresentation(const DashAdptSetInfo *adptSetInfo, std::string &mimeType)
46 {
47 DashList<DashRepresentationInfo *> representationList = adptSetInfo->representationList_;
48 for (DashRepresentationInfo *representationInfo : representationList) {
49 mimeType = representationInfo->commonAttrsAndElements_.mimeType_;
50 if (!mimeType.empty()) {
51 break;
52 }
53 }
54 }
55
DashPeriodManager(DashPeriodInfo * period)56 DashPeriodManager::DashPeriodManager(DashPeriodInfo *period)
57 {
58 SetPeriodInfo(period);
59 }
60
~DashPeriodManager()61 DashPeriodManager::~DashPeriodManager()
62 {
63 Clear();
64 }
65
Empty() const66 bool DashPeriodManager::Empty() const
67 {
68 return (this->periodInfo_ == nullptr);
69 }
70
Reset()71 void DashPeriodManager::Reset()
72 {
73 Clear();
74 this->periodInfo_ = nullptr;
75 this->previousPeriodInfo_ = nullptr;
76 }
77
Init()78 void DashPeriodManager::Init()
79 {
80 if (this->periodInfo_ == nullptr) {
81 return;
82 }
83
84 DashList<DashAdptSetInfo *> adptSets = this->periodInfo_->adptSetList_;
85 if (adptSets.size() == 0) {
86 return;
87 }
88
89 // before init, clear the init segment and adaptationset vectors
90 Clear();
91
92 ParseAdptSetList(adptSets);
93
94 ParseInitSegment();
95 }
96
Clear()97 void DashPeriodManager::Clear()
98 {
99 if (initSegment_ != nullptr) {
100 delete initSegment_;
101 initSegment_ = nullptr;
102 }
103
104 segTmpltFlag_ = 0;
105 videoAdptSetsVector_.clear();
106 audioAdptSetsVector_.clear();
107 subtitleAdptSetsVector_.clear();
108 subtitleMimeType_.clear();
109 }
110
ParseAdptSetList(DashList<DashAdptSetInfo * > adptSetList)111 void DashPeriodManager::ParseAdptSetList(DashList<DashAdptSetInfo *> adptSetList)
112 {
113 for (DashList<DashAdptSetInfo *>::iterator it = adptSetList.begin(); it != adptSetList.end(); ++it) {
114 // get the AdaptationSet type by parse attribute mimeType/contentType, if the both attributes disappear, parse
115 // element ContentComponent
116 std::string mimeType((*it)->commonAttrsAndElements_.mimeType_);
117 std::string contentType((*it)->contentType_);
118
119 DashList<DashContentCompInfo *> contentCompList((*it)->contentCompList_);
120
121 // if mimeType of AdaptationSet disappear, get mimeType from AdaptationSet.Representation
122 if (mimeType.empty()) {
123 GetMimeTypeFromRepresentation(*it, mimeType);
124 }
125
126 // if mimeType or contentType appear, parse it
127 if (!mimeType.empty()) {
128 ParseAdptSetTypeByMime(mimeType, *it);
129 } else if (!contentType.empty()) {
130 ParseAdptSetTypeByMime(contentType, *it);
131 } else if (!contentCompList.empty()) {
132 // if AdaptationSet and AdaptationSet.Representation can not find mime/contentType. we parse
133 // ContentComponent
134 ParseAdptSetTypeByComp(contentCompList, *it);
135 } else {
136 // if attributes mimeType/contentType both disappear and element ContentComponent disappear, think the
137 // AdaptationSet is video
138 videoAdptSetsVector_.push_back(*it);
139 }
140 }
141 }
142
ParseAdptSetTypeByMime(std::string mimeType,DashAdptSetInfo * adptSetInfo)143 void DashPeriodManager::ParseAdptSetTypeByMime(std::string mimeType, DashAdptSetInfo *adptSetInfo)
144 {
145 if (adptSetInfo->mimeType_.empty()) {
146 adptSetInfo->mimeType_.append(mimeType);
147 }
148
149 if (mimeType.find(VIDEO_MIME_TYPE) != std::string::npos) {
150 videoAdptSetsVector_.push_back(adptSetInfo);
151 } else if (mimeType.find(AUDIO_MIME_TYPE) != std::string::npos) {
152 audioAdptSetsVector_.push_back(adptSetInfo);
153 } else if (mimeType.find(SUBTITLE_MIME_APPLICATION) != std::string::npos ||
154 mimeType.find(SUBTITLE_MIME_TEXT) != std::string::npos) {
155 // if exist application(such as application/ttml+xml) in mimeType/contentType, we think as subtitle
156 if (subtitleMimeType_.empty()) {
157 // parse subtitle mime type first time, store as subtitleMimeType
158 subtitleMimeType_ =
159 ((mimeType.find(SUBTITLE_MIME_APPLICATION) != std::string::npos) ? SUBTITLE_MIME_APPLICATION
160 : SUBTITLE_MIME_TEXT);
161 } else if (mimeType.find(subtitleMimeType_) == std::string::npos) {
162 // only use one mimeType("application" or "text/"), skip another one
163 return;
164 }
165
166 subtitleAdptSetsVector_.push_back(adptSetInfo);
167 } else {
168 videoAdptSetsVector_.push_back(adptSetInfo);
169 }
170 }
171
ParseAdptSetTypeByComp(DashList<DashContentCompInfo * > contentCompList,DashAdptSetInfo * adptSetInfo)172 void DashPeriodManager::ParseAdptSetTypeByComp(DashList<DashContentCompInfo *> contentCompList,
173 DashAdptSetInfo *adptSetInfo)
174 {
175 if (ContainType(contentCompList, VIDEO_MIME_TYPE)) {
176 videoAdptSetsVector_.push_back(adptSetInfo);
177 } else if (ContainType(contentCompList, AUDIO_MIME_TYPE)) {
178 audioAdptSetsVector_.push_back(adptSetInfo);
179 } else if (ContainType(contentCompList, SUBTITLE_MIME_APPLICATION) ||
180 ContainType(contentCompList, SUBTITLE_MIME_TEXT)) {
181 if (subtitleMimeType_.empty()) {
182 // parse subtitle mime type first time, store as subtitleMimeType
183 subtitleMimeType_ = ((ContainType(contentCompList, SUBTITLE_MIME_APPLICATION)) ? SUBTITLE_MIME_APPLICATION
184 : SUBTITLE_MIME_TEXT);
185 } else if (!ContainType(contentCompList, subtitleMimeType_)) {
186 // only use one mimeType("application" or "text/"), skip another one
187 return;
188 }
189 subtitleAdptSetsVector_.push_back(adptSetInfo);
190 } else {
191 videoAdptSetsVector_.push_back(adptSetInfo);
192 }
193 }
194
ParseInitSegment()195 void DashPeriodManager::ParseInitSegment()
196 {
197 // ---------- init initial segment -------------------
198 if (periodInfo_->periodSegBase_ && periodInfo_->periodSegBase_->initialization_) {
199 // first get initSegment from <Period> <SegmentBase> <Initialization /> </SegmentBase> </Period>
200 initSegment_ = CloneUrlType(periodInfo_->periodSegBase_->initialization_);
201 } else if (periodInfo_->periodSegList_ &&
202 periodInfo_->periodSegList_->multSegBaseInfo_.segBaseInfo_.initialization_) {
203 // second get initSegment from <SegmentList> <Initialization sourceURL="seg-m-init.mp4"/> </SegmentList>
204 initSegment_ = CloneUrlType(periodInfo_->periodSegList_->multSegBaseInfo_.segBaseInfo_.initialization_);
205 } else if (periodInfo_->periodSegTmplt_) {
206 ParseInitSegmentBySegTmplt();
207 } else if (initSegment_ != nullptr) {
208 delete initSegment_;
209 initSegment_ = nullptr;
210 }
211
212 // if sourceUrl is not present, use BaseURL in mpd
213 }
214
ParseInitSegmentBySegTmplt()215 void DashPeriodManager::ParseInitSegmentBySegTmplt()
216 {
217 if (periodInfo_->periodSegTmplt_->multSegBaseInfo_.segBaseInfo_.initialization_) {
218 initSegment_ = CloneUrlType(periodInfo_->periodSegTmplt_->multSegBaseInfo_.segBaseInfo_.initialization_);
219 } else if (periodInfo_->periodSegTmplt_->segTmpltInitialization_.length() > 0) {
220 initSegment_ = new DashUrlType;
221 if (initSegment_ != nullptr) {
222 initSegment_->sourceUrl_ = periodInfo_->periodSegTmplt_->segTmpltInitialization_;
223 segTmpltFlag_ = 1;
224 }
225 } else if (initSegment_ != nullptr) {
226 delete initSegment_;
227 initSegment_ = nullptr;
228 }
229 }
230
SetPeriodInfo(DashPeriodInfo * period)231 void DashPeriodManager::SetPeriodInfo(DashPeriodInfo *period)
232 {
233 periodInfo_ = period;
234
235 // if periodInfo changed, update it
236 if (previousPeriodInfo_ == nullptr || previousPeriodInfo_ != period) {
237 Init();
238 previousPeriodInfo_ = period;
239 }
240 }
241
GetBaseUrlList(std::list<std::string> & baseUrlList)242 void DashPeriodManager::GetBaseUrlList(std::list<std::string> &baseUrlList)
243 {
244 if (this->periodInfo_ != nullptr) {
245 baseUrlList = this->periodInfo_->baseUrl_;
246 }
247 }
248
GetAdptSetsByStreamType(DashVector<DashAdptSetInfo * > & adptSetInfo,MediaAVCodec::MediaType streamType)249 void DashPeriodManager::GetAdptSetsByStreamType(DashVector<DashAdptSetInfo *> &adptSetInfo,
250 MediaAVCodec::MediaType streamType)
251 {
252 switch (streamType) {
253 case MediaAVCodec::MediaType::MEDIA_TYPE_VID:
254 adptSetInfo = videoAdptSetsVector_;
255 break;
256 case MediaAVCodec::MediaType::MEDIA_TYPE_AUD:
257 adptSetInfo = audioAdptSetsVector_;
258 break;
259 case MediaAVCodec::MediaType::MEDIA_TYPE_SUBTITLE:
260 adptSetInfo = subtitleAdptSetsVector_;
261 break;
262 default:
263 adptSetInfo = videoAdptSetsVector_;
264 break;
265 }
266 }
267
GetInitSegment(int32_t & flag)268 DashUrlType *DashPeriodManager::GetInitSegment(int32_t &flag)
269 {
270 flag = this->segTmpltFlag_;
271 return this->initSegment_;
272 }
273
GetPeriod()274 DashPeriodInfo *DashPeriodManager::GetPeriod()
275 {
276 return this->periodInfo_;
277 }
278
GetPreviousPeriod()279 DashPeriodInfo *DashPeriodManager::GetPreviousPeriod()
280 {
281 return this->previousPeriodInfo_;
282 }
283 } // namespace HttpPluginLite
284 } // namespace Plugin
285 } // namespace Media
286 } // namespace OHOS