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_mpd_manager.h"
17 #include "dash_mpd_util.h"
18 
19 namespace OHOS {
20 namespace Media {
21 namespace Plugins {
22 namespace HttpPlugin {
DashMpdManager(DashMpdInfo * mpdInfomation,const std::string & mpdUrlStr)23 DashMpdManager::DashMpdManager(DashMpdInfo *mpdInfomation, const std::string &mpdUrlStr)
24     : mpdInfo_(nullptr), mpdUrl_(mpdUrlStr)
25 {
26     SetMpdInfo(mpdInfomation, mpdUrlStr);
27 }
28 
Reset()29 void DashMpdManager::Reset()
30 {
31     this->mpdInfo_ = nullptr;
32     this->mpdUrl_ = "";
33 }
34 
SetMpdInfo(DashMpdInfo * mpdInfomation,const std::string & mpdUrlStr)35 void DashMpdManager::SetMpdInfo(DashMpdInfo *mpdInfomation, const std::string &mpdUrlStr)
36 {
37     this->mpdInfo_ = mpdInfomation;
38     this->mpdUrl_ = mpdUrlStr;
39 }
40 
GetPeriods() const41 const DashList<DashPeriodInfo *> &DashMpdManager::GetPeriods() const
42 {
43     return this->mpdInfo_->periodInfoList_;
44 }
45 
GetFirstPeriod()46 DashPeriodInfo *DashMpdManager::GetFirstPeriod()
47 {
48     if (this->mpdInfo_ == nullptr || this->mpdInfo_->periodInfoList_.size() == 0) {
49         return nullptr;
50     }
51 
52     return *(this->mpdInfo_->periodInfoList_.begin());
53 }
54 
GetNextPeriod(const DashPeriodInfo * period)55 DashPeriodInfo *DashMpdManager::GetNextPeriod(const DashPeriodInfo *period)
56 {
57     if (this->mpdInfo_ == nullptr || this->mpdInfo_->periodInfoList_.size() == 0) {
58         return nullptr;
59     }
60 
61     DashList<DashPeriodInfo *> periods = this->mpdInfo_->periodInfoList_;
62     for (DashList<DashPeriodInfo *>::iterator it = periods.begin(); it != periods.end(); ++it) {
63         if ((*it) == period) {
64             ++it;
65             return (it != periods.end() ? *it : nullptr);
66         }
67     }
68 
69     return nullptr;
70 }
71 
GetBaseUrlList(std::list<std::string> & baseUrlList)72 void DashMpdManager::GetBaseUrlList(std::list<std::string> &baseUrlList)
73 {
74     // if no BaseUrl in MPD Element, get base url from mpd url
75     if (this->mpdInfo_ == nullptr) {
76         return;
77     }
78 
79     if (this->mpdInfo_->baseUrl_.empty() && !this->mpdUrl_.empty()) {
80         std::string mpdUrlBase = this->mpdUrl_;
81         size_t sepCharIndex = mpdUrlBase.find('?');
82         if (sepCharIndex != std::string::npos) {
83             mpdUrlBase = mpdUrlBase.substr(0, sepCharIndex);
84         }
85 
86         if (mpdUrlBase.find('/') != std::string::npos) {
87             size_t end = mpdUrlBase.find_last_of('/');
88             std::string newBaseUrl(mpdUrlBase.substr(0, end + 1));
89             this->mpdInfo_->baseUrl_.push_back(newBaseUrl);
90         }
91     }
92 
93     baseUrlList = this->mpdInfo_->baseUrl_;
94 }
95 
GetBaseUrl()96 std::string DashMpdManager::GetBaseUrl()
97 {
98     std::string mpdUrlBase = this->mpdUrl_;
99     size_t sepCharIndex = mpdUrlBase.find('?');
100     if (sepCharIndex != std::string::npos) {
101         mpdUrlBase = mpdUrlBase.substr(0, sepCharIndex);
102     }
103 
104     std::string urlSchem;
105     size_t schemIndex = mpdUrlBase.find("://");
106     if (schemIndex != std::string::npos) {
107         size_t schemLength = strlen("://");
108         urlSchem = mpdUrlBase.substr(0, schemIndex + schemLength);
109         mpdUrlBase = mpdUrlBase.substr(schemIndex + schemLength);
110     }
111 
112     if (mpdUrlBase.find('/') != std::string::npos) {
113         size_t end = mpdUrlBase.find_last_of('/');
114         mpdUrlBase = mpdUrlBase.substr(0, end + 1);
115     }
116 
117     MakeBaseUrl(mpdUrlBase, urlSchem);
118     return urlSchem.append(mpdUrlBase);
119 }
120 
MakeBaseUrl(std::string & mpdUrlBase,std::string & urlSchem)121 void DashMpdManager::MakeBaseUrl(std::string &mpdUrlBase, std::string &urlSchem)
122 {
123     if (mpdInfo_->baseUrl_.empty()) {
124         return;
125     }
126 
127     std::string baseUrl = mpdInfo_->baseUrl_.front();
128     if (DashUrlIsAbsolute(baseUrl)) {
129         urlSchem.clear();
130         mpdUrlBase = baseUrl;
131     } else {
132         if (baseUrl.find('/') == 0) {
133             // absolute path, strip path in mpdUrl
134             size_t beginPathIndex = mpdUrlBase.find('/');
135             if (beginPathIndex != std::string::npos) {
136                 mpdUrlBase = mpdUrlBase.substr(0, beginPathIndex);
137             }
138         }
139 
140         mpdUrlBase.append(baseUrl);
141     }
142 }
143 
GetMpdInfo()144 DashMpdInfo *DashMpdManager::GetMpdInfo()
145 {
146     return this->mpdInfo_;
147 }
148 
Update(DashMpdInfo * newMpdInfo)149 void DashMpdManager::Update(DashMpdInfo *newMpdInfo)
150 {
151     SetMpdInfo(newMpdInfo, this->mpdUrl_);
152 }
153 
GetDuration(uint32_t * duration)154 void DashMpdManager::GetDuration(uint32_t *duration)
155 {
156     if (duration == nullptr || this->mpdInfo_ == nullptr) {
157         return;
158     }
159 
160     *duration = 0;
161 
162     uint32_t dur = this->mpdInfo_->mediaPresentationDuration_;
163     if (dur > 0) {
164         *duration = dur;
165         return;
166     }
167 
168     // get duration from Period
169     for (DashList<DashPeriodInfo *>::iterator it = this->mpdInfo_->periodInfoList_.begin();
170          it != this->mpdInfo_->periodInfoList_.end(); ++it) {
171         dur += (*it)->duration_;
172     }
173 
174     // count duration by segments not implement
175     *duration = dur;
176     return;
177 }
178 } // namespace HttpPluginLite
179 } // namespace Plugin
180 } // namespace Media
181 } // namespace OHOS