refactor: merge Period::ProtectedAdaptationSetMap into AdaptationSet (#844)

---------

Co-authored-by: Cosmin Stejerean <cstejerean@meta.com>
This commit is contained in:
sr90 2024-05-02 19:11:04 -07:00 committed by GitHub
parent bb104fef5d
commit a54e745cf8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 103 additions and 108 deletions

View File

@ -189,11 +189,73 @@ AdaptationSet::AdaptationSet(const std::string& language,
uint32_t* counter) uint32_t* counter)
: representation_counter_(counter), : representation_counter_(counter),
language_(language), language_(language),
mpd_options_(mpd_options) { mpd_options_(mpd_options),
protected_content_(nullptr) {
DCHECK(counter); DCHECK(counter);
} }
AdaptationSet::~AdaptationSet() {} AdaptationSet::~AdaptationSet() {
delete protected_content_;
}
void AdaptationSet::set_protected_content(const MediaInfo& media_info) {
DCHECK(!protected_content_);
protected_content_ =
new MediaInfo::ProtectedContent(media_info.protected_content());
}
// The easiest way to check whether two protobufs are equal, is to compare the
// serialized version.
bool ProtectedContentEq(
const MediaInfo::ProtectedContent& content_protection1,
const MediaInfo::ProtectedContent& content_protection2) {
return content_protection1.SerializeAsString() ==
content_protection2.SerializeAsString();
}
bool AdaptationSet::MatchAdaptationSet(
const MediaInfo& media_info,
bool content_protection_in_adaptation_set) {
if (codec_ != GetBaseCodec(media_info))
return false;
if (!content_protection_in_adaptation_set)
return true;
if (!protected_content_)
return !media_info.has_protected_content();
if (!media_info.has_protected_content())
return false;
return ProtectedContentEq(*protected_content_,
media_info.protected_content());
}
std::set<std::string> GetUUIDs(
const MediaInfo::ProtectedContent* protected_content) {
std::set<std::string> uuids;
for (const auto& entry : protected_content->content_protection_entry())
uuids.insert(entry.uuid());
return uuids;
}
bool AdaptationSet::SwitchableAdaptationSet(
const AdaptationSet& adaptation_set) {
// adaptation sets are switchable if both are not protected
if (!protected_content_ && !adaptation_set.protected_content()) {
return true;
}
// or if both are protected and have the same UUID
if (protected_content_ && adaptation_set.protected_content()) {
return GetUUIDs(protected_content_) ==
GetUUIDs(adaptation_set.protected_content());
}
return false;
}
Representation* AdaptationSet::AddRepresentation(const MediaInfo& media_info) { Representation* AdaptationSet::AddRepresentation(const MediaInfo& media_info) {
const uint32_t representation_id = media_info.has_index() const uint32_t representation_id = media_info.has_index()

View File

@ -18,6 +18,7 @@
#include <vector> #include <vector>
#include <packager/mpd/base/xml/xml_node.h> #include <packager/mpd/base/xml/xml_node.h>
#include "packager/mpd/base/media_info.pb.h"
namespace shaka { namespace shaka {
@ -208,6 +209,29 @@ class AdaptationSet {
transfer_characteristics_ = transfer_characteristics; transfer_characteristics_ = transfer_characteristics;
}; };
/// Return ProtectedContent.
const MediaInfo::ProtectedContent* protected_content() const {
return protected_content_;
};
/// Set AdaptationSet@protected_content.
/// @param media_info to extract the ProtectedContent from.
void set_protected_content(const MediaInfo& media_info);
/// Check if the protected content associated with this AdaptationSet matches
/// with the one in |media_info|.
/// @param media_info to extract ProtectedContent from.
/// @param content_protection_in_adaptation_set to indicate if there is
/// protected content in AdaptationSet.
/// @return true if there is a match.
bool MatchAdaptationSet(const MediaInfo& media_info,
bool content_protection_in_adaptation_set);
/// Check if the adaptation sets are switchable.
/// @param adaptation_set to compare this AdaptationSet with.
/// @return true if AdaptationSets are switchable.
bool SwitchableAdaptationSet(const AdaptationSet& adaptation_set);
protected: protected:
/// @param language is the language of this AdaptationSet. Mainly relevant for /// @param language is the language of this AdaptationSet. Mainly relevant for
/// audio. /// audio.
@ -357,6 +381,9 @@ class AdaptationSet {
// The label of this AdaptationSet. // The label of this AdaptationSet.
std::string label_; std::string label_;
// ProtectedContent of this AdaptationSet.
MediaInfo::ProtectedContent* protected_content_;
}; };
} // namespace shaka } // namespace shaka

View File

@ -17,23 +17,6 @@
namespace shaka { namespace shaka {
namespace { namespace {
// The easiest way to check whether two protobufs are equal, is to compare the
// serialized version.
bool ProtectedContentEq(
const MediaInfo::ProtectedContent& content_protection1,
const MediaInfo::ProtectedContent& content_protection2) {
return content_protection1.SerializeAsString() ==
content_protection2.SerializeAsString();
}
std::set<std::string> GetUUIDs(
const MediaInfo::ProtectedContent& protected_content) {
std::set<std::string> uuids;
for (const auto& entry : protected_content.content_protection_entry())
uuids.insert(entry.uuid());
return uuids;
}
const std::string& GetDefaultAudioLanguage(const MpdOptions& mpd_options) { const std::string& GetDefaultAudioLanguage(const MpdOptions& mpd_options) {
return mpd_options.mpd_params.default_language; return mpd_options.mpd_params.default_language;
} }
@ -91,8 +74,8 @@ AdaptationSet* Period::GetOrCreateAdaptationSet(
std::list<AdaptationSet*>& adaptation_sets = adaptation_set_list_map_[key]; std::list<AdaptationSet*>& adaptation_sets = adaptation_set_list_map_[key];
for (AdaptationSet* adaptation_set : adaptation_sets) { for (AdaptationSet* adaptation_set : adaptation_sets) {
if (protected_adaptation_set_map_.Match( if (adaptation_set->MatchAdaptationSet(
*adaptation_set, media_info, content_protection_in_adaptation_set)) media_info, content_protection_in_adaptation_set))
return adaptation_set; return adaptation_set;
} }
@ -107,14 +90,8 @@ AdaptationSet* Period::GetOrCreateAdaptationSet(
return nullptr; return nullptr;
} }
if (content_protection_in_adaptation_set &&
media_info.has_protected_content()) {
protected_adaptation_set_map_.Register(*new_adaptation_set, media_info);
AddContentProtectionElements(media_info, new_adaptation_set.get());
}
for (AdaptationSet* adaptation_set : adaptation_sets) { for (AdaptationSet* adaptation_set : adaptation_sets) {
if (protected_adaptation_set_map_.Switchable(*adaptation_set, if (adaptation_set->SwitchableAdaptationSet(*new_adaptation_set)) {
*new_adaptation_set)) {
adaptation_set->AddAdaptationSetSwitching(new_adaptation_set.get()); adaptation_set->AddAdaptationSetSwitching(new_adaptation_set.get());
new_adaptation_set->AddAdaptationSetSwitching(adaptation_set); new_adaptation_set->AddAdaptationSetSwitching(adaptation_set);
} }
@ -307,6 +284,13 @@ bool Period::SetNewAdaptationSetAttributes(
// In practice it doesn't really make sense to adapt between text tracks. // In practice it doesn't really make sense to adapt between text tracks.
new_adaptation_set->ForceSetSegmentAlignment(true); new_adaptation_set->ForceSetSegmentAlignment(true);
} }
if (content_protection_in_adaptation_set &&
media_info.has_protected_content()) {
new_adaptation_set->set_protected_content(media_info);
AddContentProtectionElements(media_info, new_adaptation_set);
}
return true; return true;
} }
@ -331,11 +315,9 @@ AdaptationSet* Period::FindMatchingAdaptationSetForTrickPlay(
adaptation_sets = &trickplay_cache_[*adaptation_set_key]; adaptation_sets = &trickplay_cache_[*adaptation_set_key];
} }
for (AdaptationSet* adaptation_set : *adaptation_sets) { for (AdaptationSet* adaptation_set : *adaptation_sets) {
if (protected_adaptation_set_map_.Match( if (adaptation_set->MatchAdaptationSet(
*adaptation_set, media_info, media_info, content_protection_in_adaptation_set))
content_protection_in_adaptation_set)) {
return adaptation_set; return adaptation_set;
}
} }
return nullptr; return nullptr;
@ -349,55 +331,6 @@ std::string Period::GetAdaptationSetKeyForTrickPlay(
mpd_options_.mpd_params.allow_codec_switching); mpd_options_.mpd_params.allow_codec_switching);
} }
void Period::ProtectedAdaptationSetMap::Register(
const AdaptationSet& adaptation_set,
const MediaInfo& media_info) {
CHECK(protected_content_map_.find(&adaptation_set) ==
protected_content_map_.end());
protected_content_map_[&adaptation_set] = media_info.protected_content();
}
bool Period::ProtectedAdaptationSetMap::Match(
const AdaptationSet& adaptation_set,
const MediaInfo& media_info,
bool content_protection_in_adaptation_set) {
if (adaptation_set.codec() != GetBaseCodec(media_info))
return false;
if (!content_protection_in_adaptation_set)
return true;
const auto protected_content_it =
protected_content_map_.find(&adaptation_set);
// If the AdaptationSet ID is not registered in the map, then it is clear
// content.
if (protected_content_it == protected_content_map_.end())
return !media_info.has_protected_content();
if (!media_info.has_protected_content())
return false;
return ProtectedContentEq(protected_content_it->second,
media_info.protected_content());
}
bool Period::ProtectedAdaptationSetMap::Switchable(
const AdaptationSet& adaptation_set_a,
const AdaptationSet& adaptation_set_b) {
const auto protected_content_it_a =
protected_content_map_.find(&adaptation_set_a);
const auto protected_content_it_b =
protected_content_map_.find(&adaptation_set_b);
if (protected_content_it_a == protected_content_map_.end())
return protected_content_it_b == protected_content_map_.end();
if (protected_content_it_b == protected_content_map_.end())
return false;
// Get all the UUIDs of the AdaptationSet. If another AdaptationSet has the
// same UUIDs then those are switchable.
return GetUUIDs(protected_content_it_a->second) ==
GetUUIDs(protected_content_it_b->second);
}
Period::~Period() { Period::~Period() {
if (!trickplay_cache_.empty()) { if (!trickplay_cache_.empty()) {
LOG(WARNING) << "Trickplay adaptation set did not get a valid adaptation " LOG(WARNING) << "Trickplay adaptation set did not get a valid adaptation "

View File

@ -133,33 +133,6 @@ class Period {
// grouping key. These AdaptationSets still have not found reference // grouping key. These AdaptationSets still have not found reference
// AdaptationSet. // AdaptationSet.
std::map<std::string, std::list<AdaptationSet*>> trickplay_cache_; std::map<std::string, std::list<AdaptationSet*>> trickplay_cache_;
// Tracks ProtectedContent in AdaptationSet.
class ProtectedAdaptationSetMap {
public:
ProtectedAdaptationSetMap() = default;
// Register the |adaptation_set| with associated |media_info| in the map.
void Register(const AdaptationSet& adaptation_set,
const MediaInfo& media_info);
// Check if the protected content associated with |adaptation_set| matches
// with the one in |media_info|.
bool Match(const AdaptationSet& adaptation_set,
const MediaInfo& media_info,
bool content_protection_in_adaptation_set);
// Check if the two adaptation sets are switchable.
bool Switchable(const AdaptationSet& adaptation_set_a,
const AdaptationSet& adaptation_set_b);
private:
ProtectedAdaptationSetMap(const ProtectedAdaptationSetMap&) = delete;
ProtectedAdaptationSetMap& operator=(const ProtectedAdaptationSetMap&) =
delete;
// AdaptationSet => ProtectedContent map.
std::map<const AdaptationSet*, MediaInfo::ProtectedContent>
protected_content_map_;
};
ProtectedAdaptationSetMap protected_adaptation_set_map_;
}; };
} // namespace shaka } // namespace shaka