Add a method to add roles to AdaptationSets

Change-Id: Ib0de3b2817870c58fda9bcabf4686c27d60a72c5
This commit is contained in:
Rintaro Kuroiwa 2015-06-26 16:00:41 -07:00
parent 4e2b70c939
commit f492cccc1d
5 changed files with 104 additions and 0 deletions

View File

@ -273,6 +273,33 @@ void AddPictureAspectRatio(
picture_aspect_ratio->insert(par);
}
std::string RoleToText(AdaptationSet::Role role) {
// Using switch so that the compiler can detect whether there is a case that's
// not being handled.
switch (role) {
case AdaptationSet::kRoleCaption:
return "caption";
case AdaptationSet::kRoleSubtitle:
return "subtitle";
case AdaptationSet::kRoleMain:
return "main";
case AdaptationSet::kRoleAlternate:
return "alternate";
case AdaptationSet::kRoleSupplementary:
return "supplementary";
case AdaptationSet::kRoleCommentary:
return "commentary";
case AdaptationSet::kRoleDub:
return "dub";
default:
NOTREACHED();
return "";
}
NOTREACHED();
return "";
}
// Spooky static initialization/cleanup of libxml.
class LibXmlInitializer {
public:
@ -619,6 +646,10 @@ void AdaptationSet::AddContentProtectionElement(
RemoveDuplicateAttributes(&content_protection_elements_.back());
}
void AdaptationSet::AddRole(Role role) {
roles_.insert(role);
}
// Creates a copy of <AdaptationSet> xml element, iterate thru all the
// <Representation> (child) elements and add them to the copy.
xml::ScopedXmlPtr<xmlNode>::type AdaptationSet::GetXml() {
@ -670,6 +701,12 @@ xml::ScopedXmlPtr<xmlNode>::type AdaptationSet::GetXml() {
if (group_ >= 0)
adaptation_set.SetIntegerAttribute("group", group_);
for (std::set<Role>::const_iterator role_it = roles_.begin();
role_it != roles_.end(); ++role_it) {
adaptation_set.AddRoleElement("urn:mpeg:dash:role:2011",
RoleToText(*role_it));
}
return adaptation_set.PassScopedPtr();
}

View File

@ -71,6 +71,8 @@ class MpdBuilder {
void AddBaseUrl(const std::string& base_url);
/// Adds <AdaptationSet> to the MPD.
/// @param lang is the language of the AdaptationSet. This can be empty for
/// videos, for example.
/// @return The new adaptation set, which is owned by this instance.
AdaptationSet* AddAdaptationSet(const std::string& lang);
@ -153,6 +155,19 @@ class MpdBuilder {
/// <ContentProtection> elements to the AdaptationSet element.
class AdaptationSet {
public:
// The role for this AdaptationSet. These values are used to add a Role
// element to the AdaptationSet with schemeIdUri=urn:mpeg:dash:role:2011.
// See ISO/IEC 23009-1:2012 section 5.8.5.5.
enum Role {
kRoleCaption,
kRoleSubtitle,
kRoleMain,
kRoleAlternate,
kRoleSupplementary,
kRoleCommentary,
kRoleDub
};
~AdaptationSet();
/// Create a Representation instance using @a media_info.
@ -169,6 +184,12 @@ class AdaptationSet {
/// then the former is used.
void AddContentProtectionElement(const ContentProtectionElement& element);
/// Set the Role element for this AdaptationSet.
/// The Role element's is schemeIdUri='urn:mpeg:dash:role:2011'.
/// See ISO/IEC 23009-1:2012 section 5.8.5.5.
/// @param role of this AdaptationSet.
void AddRole(Role role);
/// Makes a copy of AdaptationSet xml element with its child Representation
/// and ContentProtection elements.
/// @return On success returns a non-NULL ScopedXmlPtr. Otherwise returns a
@ -255,6 +276,9 @@ class AdaptationSet {
// in this set.
std::set<std::string> picture_aspect_ratio_;
// The roles of this AdaptationSet.
std::set<Role> roles_;
DISALLOW_COPY_AND_ASSIGN(AdaptationSet);
};

View File

@ -487,6 +487,36 @@ TEST_F(CommonMpdBuilderTest, CheckAdaptationSetId) {
ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kAdaptationSetId, &adaptation_set));
}
// Verify AdaptationSet::AddRole() works for "main" role.
TEST_F(CommonMpdBuilderTest, AdaptationAddRoleElementMain) {
MpdBuilder mpd_builder(MpdBuilder::kStatic, MpdOptions());
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
adaptation_set->AddRole(AdaptationSet::kRoleMain);
xml::ScopedXmlPtr<xmlNode>::type adaptation_set_xml(adaptation_set->GetXml());
// The empty contentType is sort of a side effect of being able to generate an
// MPD without adding any Representations.
const char kExpectedOutput[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<MPD xmlns=\"urn:mpeg:DASH:schema:MPD:2011\"\n"
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
" xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd\"\n"
" minBufferTime=\"PT2S\" type=\"static\"\n"
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
" mediaPresentationDuration=\"PT0S\">\n"
" <Period>\n"
" <AdaptationSet id=\"0\" contentType=\"\">\n"
" <Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"main\"/>\n"
" </AdaptationSet>\n"
" </Period>\n"
"</MPD>";
std::string mpd_output;
EXPECT_TRUE(mpd_builder.ToString(&mpd_output));
EXPECT_TRUE(XmlEqual(kExpectedOutput, mpd_output))
<< "Expected " << kExpectedOutput << std::endl << "Actual: " << mpd_output;
}
// Verify that if all video Representations in an AdaptationSet have the same
// frame rate, AdaptationSet also has a frameRate attribute.
TEST_F(CommonMpdBuilderTest, AdapatationSetFrameRate) {

View File

@ -320,6 +320,14 @@ AdaptationSetXmlNode::AdaptationSetXmlNode()
: RepresentationBaseXmlNode("AdaptationSet") {}
AdaptationSetXmlNode::~AdaptationSetXmlNode() {}
void AdaptationSetXmlNode::AddRoleElement(const std::string& scheme_id_uri,
const std::string& value) {
XmlNode role("Role");
role.SetStringAttribute("schemeIdUri", scheme_id_uri);
role.SetStringAttribute("value", value);
AddChild(role.PassScopedPtr());
}
RepresentationXmlNode::RepresentationXmlNode()
: RepresentationBaseXmlNode("Representation") {}
RepresentationXmlNode::~RepresentationXmlNode() {}

View File

@ -117,6 +117,11 @@ class AdaptationSetXmlNode : public RepresentationBaseXmlNode {
AdaptationSetXmlNode();
virtual ~AdaptationSetXmlNode();
/// @param scheme_id_uri is content of the schemeIdUri attribute.
/// @param value is the content of value attribute.
void AddRoleElement(const std::string& scheme_id_uri,
const std::string& value);
private:
DISALLOW_COPY_AND_ASSIGN(AdaptationSetXmlNode);
};