7 #include "packager/mpd/base/period.h" 9 #include "packager/base/stl_util.h" 10 #include "packager/mpd/base/adaptation_set.h" 11 #include "packager/mpd/base/mpd_options.h" 12 #include "packager/mpd/base/mpd_utils.h" 13 #include "packager/mpd/base/xml/xml_node.h" 20 bool ProtectedContentEq(
21 const MediaInfo::ProtectedContent& content_protection1,
22 const MediaInfo::ProtectedContent& content_protection2) {
23 return content_protection1.SerializeAsString() ==
24 content_protection2.SerializeAsString();
27 std::set<std::string> GetUUIDs(
28 const MediaInfo::ProtectedContent& protected_content) {
29 std::set<std::string> uuids;
30 for (
const auto& entry : protected_content.content_protection_entry())
31 uuids.insert(entry.uuid());
38 double start_time_in_seconds,
40 base::AtomicSequenceNumber* adaptation_set_counter,
41 base::AtomicSequenceNumber* representation_counter)
43 start_time_in_seconds_(start_time_in_seconds),
44 mpd_options_(mpd_options),
45 adaptation_set_counter_(adaptation_set_counter),
46 representation_counter_(representation_counter) {}
49 const MediaInfo& media_info,
50 bool content_protection_in_adaptation_set) {
54 const std::string key = GetAdaptationSetKey(media_info);
55 std::list<AdaptationSet*>& adaptation_sets = adaptation_set_list_map_[key];
56 if (content_protection_in_adaptation_set) {
58 if (protected_adaptation_set_map_.Match(*adaptation_set, media_info))
59 return adaptation_set;
62 if (!adaptation_sets.empty()) {
63 DCHECK_EQ(adaptation_sets.size(), 1u);
64 return adaptation_sets.front();
69 std::string language = GetLanguage(media_info);
70 std::unique_ptr<AdaptationSet> new_adaptation_set =
71 NewAdaptationSet(adaptation_set_counter_->GetNext(), language,
72 mpd_options_, representation_counter_);
73 if (!SetNewAdaptationSetAttributes(language, media_info, adaptation_sets,
74 new_adaptation_set.get())) {
78 if (content_protection_in_adaptation_set &&
79 media_info.has_protected_content()) {
80 protected_adaptation_set_map_.Register(*new_adaptation_set, media_info);
84 if (protected_adaptation_set_map_.Switchable(*adaptation_set,
85 *new_adaptation_set)) {
86 adaptation_set->AddAdaptationSetSwitching(new_adaptation_set->id());
87 new_adaptation_set->AddAdaptationSetSwitching(adaptation_set->id());
92 adaptation_sets.push_back(adaptation_set_ptr);
93 adaptation_set_map_[adaptation_set_ptr->id()] = std::move(new_adaptation_set);
94 return adaptation_set_ptr;
103 for (
const auto& adaptation_set_pair : adaptation_set_map_) {
104 xml::scoped_xml_ptr<xmlNode> child(adaptation_set_pair.second->GetXml());
105 if (!child || !period.
AddChild(std::move(child)))
109 if (duration_seconds_ != 0) {
111 SecondsToXmlDuration(duration_seconds_));
112 }
else if (mpd_options_.mpd_type == MpdType::kDynamic ||
113 start_time_in_seconds_ != 0) {
115 SecondsToXmlDuration(start_time_in_seconds_));
121 std::list<AdaptationSet*> adaptation_sets;
122 for (
const auto& adaptation_set_pair : adaptation_set_map_) {
123 adaptation_sets.push_back(adaptation_set_pair.second.get());
125 return adaptation_sets;
128 std::unique_ptr<AdaptationSet> Period::NewAdaptationSet(
129 uint32_t adaptation_set_id,
130 const std::string& language,
132 base::AtomicSequenceNumber* representation_counter) {
134 adaptation_set_id, language, options, representation_counter));
137 bool Period::SetNewAdaptationSetAttributes(
138 const std::string& language,
139 const MediaInfo& media_info,
140 const std::list<AdaptationSet*>& adaptation_sets,
142 if (!language.empty() && language == mpd_options_.mpd_params.
default_language)
143 new_adaptation_set->
AddRole(AdaptationSet::kRoleMain);
145 if (media_info.has_video_info()) {
148 if (adaptation_sets.size() > 1) {
149 new_adaptation_set->
AddRole(AdaptationSet::kRoleMain);
150 }
else if (adaptation_sets.size() == 1) {
151 (*adaptation_sets.begin())->AddRole(AdaptationSet::kRoleMain);
152 new_adaptation_set->
AddRole(AdaptationSet::kRoleMain);
155 if (media_info.video_info().has_playback_rate()) {
156 uint32_t trick_play_reference_id = 0;
157 if (!FindOriginalAdaptationSetForTrickPlay(media_info,
158 &trick_play_reference_id)) {
159 LOG(ERROR) <<
"Failed to find main adaptation set for trick play.";
162 DCHECK_NE(new_adaptation_set->id(), trick_play_reference_id);
165 }
else if (media_info.has_text_info()) {
174 bool Period::FindOriginalAdaptationSetForTrickPlay(
175 const MediaInfo& media_info,
176 uint32_t* main_adaptation_set_id) {
177 MediaInfo media_info_no_trickplay = media_info;
178 media_info_no_trickplay.mutable_video_info()->clear_playback_rate();
180 std::string key = GetAdaptationSetKey(media_info_no_trickplay);
181 const std::list<AdaptationSet*>& adaptation_sets =
182 adaptation_set_list_map_[key];
184 if (protected_adaptation_set_map_.Match(*adaptation_set, media_info)) {
185 *main_adaptation_set_id = adaptation_set->id();
192 void Period::ProtectedAdaptationSetMap::Register(
194 const MediaInfo& media_info) {
195 DCHECK(!ContainsKey(protected_content_map_, adaptation_set.id()));
196 protected_content_map_[adaptation_set.id()] = media_info.protected_content();
199 bool Period::ProtectedAdaptationSetMap::Match(
201 const MediaInfo& media_info) {
202 const auto protected_content_it =
203 protected_content_map_.find(adaptation_set.id());
206 if (protected_content_it == protected_content_map_.end())
207 return !media_info.has_protected_content();
208 if (!media_info.has_protected_content())
210 return ProtectedContentEq(protected_content_it->second,
211 media_info.protected_content());
214 bool Period::ProtectedAdaptationSetMap::Switchable(
217 const auto protected_content_it_a =
218 protected_content_map_.find(adaptation_set_a.id());
219 const auto protected_content_it_b =
220 protected_content_map_.find(adaptation_set_b.id());
222 if (protected_content_it_a == protected_content_map_.end())
223 return protected_content_it_b == protected_content_map_.end();
224 if (protected_content_it_b == protected_content_map_.end())
228 return GetUUIDs(protected_content_it_a->second) ==
229 GetUUIDs(protected_content_it_b->second);
std::string default_language
virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
xml::scoped_xml_ptr< xmlNode > GetXml() const
scoped_xml_ptr< xmlNode > PassScopedPtr()
All the methods that are virtual are virtual for mocking.
void SetStringAttribute(const char *attribute_name, const std::string &attribute)
bool AddChild(scoped_xml_ptr< xmlNode > child)
virtual void AddTrickPlayReferenceId(uint32_t id)
virtual void AddRole(Role role)
void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
virtual void ForceSetSegmentAlignment(bool segment_alignment)
const std::list< AdaptationSet * > GetAdaptationSets() const
Period(uint32_t period_id, double start_time_in_seconds, const MpdOptions &mpd_options, base::AtomicSequenceNumber *adaptation_set_counter, base::AtomicSequenceNumber *representation_counter)