diff --git a/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd
index 4a93b551c3..ebc2354c38 100644
--- a/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd
@@ -3,7 +3,7 @@
-
+
AAAAMHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABAxMjM0NTY3ODkwMTIzNDU2
diff --git a/packager/app/test/testdata/bear-640x360-av-cenc-iop-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cenc-iop-golden.mpd
index 10667545aa..53b2a086a9 100644
--- a/packager/app/test/testdata/bear-640x360-av-cenc-iop-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-cenc-iop-golden.mpd
@@ -7,7 +7,7 @@
AAAAMHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABAxMjM0NTY3ODkwMTIzNDU2
-
+
output_video.mp4
diff --git a/packager/app/test/testdata/bear-640x360-av-golden.mpd b/packager/app/test/testdata/bear-640x360-av-golden.mpd
index a5a8c9b634..971115fdfd 100644
--- a/packager/app/test/testdata/bear-640x360-av-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-golden.mpd
@@ -3,7 +3,7 @@
-
+
output_video.mp4
diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd
index 836af9866d..dcb921e2d6 100644
--- a/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd
@@ -3,7 +3,7 @@
-
+
AAAAMHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABAxMjM0NTY3ODkwMTIzNDU2
diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-iop-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-iop-golden.mpd
index 4dc639a9fd..deb01bae4b 100644
--- a/packager/app/test/testdata/bear-640x360-av-live-cenc-iop-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-iop-golden.mpd
@@ -7,7 +7,7 @@
AAAAMHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABAxMjM0NTY3ODkwMTIzNDU2
-
+
diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd
index c438cd3b37..04bd50f74f 100644
--- a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd
@@ -3,7 +3,7 @@
-
+
diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-iop-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-iop-golden.mpd
index 1d38bb188c..e7dcb2ae89 100644
--- a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-iop-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-iop-golden.mpd
@@ -5,7 +5,7 @@
-
+
diff --git a/packager/app/test/testdata/bear-640x360-av-live-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-golden.mpd
index 94cf9ccc2b..8917ceab39 100644
--- a/packager/app/test/testdata/bear-640x360-av-live-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-av-live-golden.mpd
@@ -3,7 +3,7 @@
-
+
diff --git a/packager/app/test/testdata/bear-640x360-avt-golden.mpd b/packager/app/test/testdata/bear-640x360-avt-golden.mpd
index c0e04a7a91..6a2d908edb 100644
--- a/packager/app/test/testdata/bear-640x360-avt-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-avt-golden.mpd
@@ -8,7 +8,7 @@
-
+
output_video.mp4
diff --git a/packager/app/test/testdata/bear-640x360-hevc-v-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-hevc-v-cenc-golden.mpd
index 7dff2a0281..31e5ae397b 100644
--- a/packager/app/test/testdata/bear-640x360-hevc-v-cenc-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-hevc-v-cenc-golden.mpd
@@ -3,7 +3,7 @@
-
+
AAAAMHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABAxMjM0NTY3ODkwMTIzNDU2
diff --git a/packager/app/test/testdata/bear-640x360-v-golden.mpd b/packager/app/test/testdata/bear-640x360-v-golden.mpd
index c374b9fd55..644644fec2 100644
--- a/packager/app/test/testdata/bear-640x360-v-golden.mpd
+++ b/packager/app/test/testdata/bear-640x360-v-golden.mpd
@@ -3,7 +3,7 @@
-
+
output_0.mp4
diff --git a/packager/mpd/base/mpd_builder.cc b/packager/mpd/base/mpd_builder.cc
index 6a25ed9707..8dbd6386cf 100644
--- a/packager/mpd/base/mpd_builder.cc
+++ b/packager/mpd/base/mpd_builder.cc
@@ -39,7 +39,8 @@ namespace {
const int kAdaptationSetGroupNotSet = -1;
-AdaptationSet::Role MediaInfoTextTypeToRole(MediaInfo::TextInfo::TextType type) {
+AdaptationSet::Role MediaInfoTextTypeToRole(
+ MediaInfo::TextInfo::TextType type) {
switch (type) {
case MediaInfo::TextInfo::UNKNOWN:
LOG(WARNING) << "Unknown text type, assuming subtitle.";
@@ -731,27 +732,16 @@ void AdaptationSet::AddRole(Role role) {
// Creates a copy of xml element, iterate thru all the
// (child) elements and add them to the copy.
+// Set all the attributes first and then add the children elements so that flags
+// can be passed to Representation to avoid setting redundant attributes. For
+// example, if AdaptationSet@width is set, then Representation@width is
+// redundant and should not be set.
xml::scoped_xml_ptr AdaptationSet::GetXml() {
AdaptationSetXmlNode adaptation_set;
- if (!adaptation_set.AddContentProtectionElements(
- content_protection_elements_)) {
- return xml::scoped_xml_ptr();
- }
- for (std::set::const_iterator role_it = roles_.begin();
- role_it != roles_.end(); ++role_it) {
- adaptation_set.AddRoleElement("urn:mpeg:dash:role:2011",
- RoleToText(*role_it));
- }
-
- std::list::iterator representation_it =
- representations_.begin();
-
- for (; representation_it != representations_.end(); ++representation_it) {
- xml::scoped_xml_ptr child((*representation_it)->GetXml());
- if (!child || !adaptation_set.AddChild(child.Pass()))
- return xml::scoped_xml_ptr();
- }
+ bool suppress_representation_width = false;
+ bool suppress_representation_height = false;
+ bool suppress_representation_frame_rate = false;
adaptation_set.SetId(id_);
adaptation_set.SetStringAttribute("contentType", content_type_);
@@ -761,17 +751,20 @@ xml::scoped_xml_ptr AdaptationSet::GetXml() {
// Note that std::{set,map} are ordered, so the last element is the max value.
if (video_widths_.size() == 1) {
+ suppress_representation_width = true;
adaptation_set.SetIntegerAttribute("width", *video_widths_.begin());
} else if (video_widths_.size() > 1) {
adaptation_set.SetIntegerAttribute("maxWidth", *video_widths_.rbegin());
}
if (video_heights_.size() == 1) {
+ suppress_representation_height = true;
adaptation_set.SetIntegerAttribute("height", *video_heights_.begin());
} else if (video_heights_.size() > 1) {
adaptation_set.SetIntegerAttribute("maxHeight", *video_heights_.rbegin());
}
if (video_frame_rates_.size() == 1) {
+ suppress_representation_frame_rate = true;
adaptation_set.SetStringAttribute("frameRate",
video_frame_rates_.begin()->second);
} else if (video_frame_rates_.size() > 1) {
@@ -779,7 +772,8 @@ xml::scoped_xml_ptr AdaptationSet::GetXml() {
video_frame_rates_.rbegin()->second);
}
- // Note: must be checked before checking segments_aligned_ (below).
+ // Note: must be checked before checking segments_aligned_ (below). So that
+ // segments_aligned_ is set before checking below.
if (mpd_type_ == MpdBuilder::kStatic) {
CheckVodSegmentAlignment();
}
@@ -797,6 +791,25 @@ xml::scoped_xml_ptr AdaptationSet::GetXml() {
if (group_ >= 0)
adaptation_set.SetIntegerAttribute("group", group_);
+ if (!adaptation_set.AddContentProtectionElements(
+ content_protection_elements_)) {
+ return xml::scoped_xml_ptr();
+ }
+ for (AdaptationSet::Role role : roles_)
+ adaptation_set.AddRoleElement("urn:mpeg:dash:role:2011", RoleToText(role));
+
+ for (Representation* representation : representations_) {
+ if (suppress_representation_width)
+ representation->SuppressOnce(Representation::kSuppressWidth);
+ if (suppress_representation_height)
+ representation->SuppressOnce(Representation::kSuppressHeight);
+ if (suppress_representation_frame_rate)
+ representation->SuppressOnce(Representation::kSuppressFrameRate);
+ xml::scoped_xml_ptr child(representation->GetXml());
+ if (!child || !adaptation_set.AddChild(child.Pass()))
+ return xml::scoped_xml_ptr();
+ }
+
return adaptation_set.PassScopedPtr();
}
@@ -1009,7 +1022,8 @@ Representation::Representation(
bandwidth_estimator_(BandwidthEstimator::kUseAllBlocks),
mpd_options_(mpd_options),
start_number_(1),
- state_change_listener_(state_change_listener.Pass()) {}
+ state_change_listener_(state_change_listener.Pass()),
+ output_suppression_flags_(0) {}
Representation::~Representation() {}
@@ -1131,7 +1145,11 @@ xml::scoped_xml_ptr Representation::GetXml() {
const bool has_audio_info = media_info_.has_audio_info();
if (has_video_info &&
- !representation.AddVideoInfo(media_info_.video_info())) {
+ !representation.AddVideoInfo(
+ media_info_.video_info(),
+ !(output_suppression_flags_ & kSuppressWidth),
+ !(output_suppression_flags_ & kSuppressHeight),
+ !(output_suppression_flags_ & kSuppressFrameRate))) {
LOG(ERROR) << "Failed to add video info to Representation XML.";
return xml::scoped_xml_ptr();
}
@@ -1162,9 +1180,14 @@ xml::scoped_xml_ptr Representation::GetXml() {
// TODO(rkuroiwa): It is likely that all representations have the exact same
// SegmentTemplate. Optimize and propagate the tag up to AdaptationSet level.
+ output_suppression_flags_ = 0;
return representation.PassScopedPtr();
}
+void Representation::SuppressOnce(SuppressFlag flag) {
+ output_suppression_flags_ |= flag;
+}
+
bool Representation::HasRequiredMediaInfoFields() {
if (HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)) {
LOG(ERROR) << "MediaInfo cannot have both VOD and Live fields.";
diff --git a/packager/mpd/base/mpd_builder.h b/packager/mpd/base/mpd_builder.h
index d296bbfc1b..e58317994d 100644
--- a/packager/mpd/base/mpd_builder.h
+++ b/packager/mpd/base/mpd_builder.h
@@ -414,6 +414,12 @@ class RepresentationStateChangeListener {
/// well as optional ContentProtection elements for that stream.
class Representation {
public:
+ enum SuppressFlag {
+ kSuppressWidth = 1,
+ kSuppressHeight = 2,
+ kSuppressFrameRate = 4,
+ };
+
virtual ~Representation();
/// Tries to initialize the instance. If this does not succeed, the instance
@@ -470,6 +476,16 @@ class Representation {
/// @return Copy of .
xml::scoped_xml_ptr GetXml();
+ /// By calling this methods, the next time GetXml() is
+ /// called, the corresponding attributes will not be set.
+ /// For example, if SuppressOnce(kSuppressWidth) is called, then GetXml() will
+ /// return a element without a @width attribute.
+ /// Note that it only applies to the next call to GetXml(), calling GetXml()
+ /// again without calling this methods will return a element
+ /// with the attribute.
+ /// This may be called multiple times to set different (or the same) flags.
+ void SuppressOnce(SuppressFlag flag);
+
/// @return ID number for .
uint32_t id() const { return id_; }
@@ -540,6 +556,9 @@ class Representation {
// right methods at right timings.
scoped_ptr state_change_listener_;
+ // Bit vector for tracking witch attributes should not be output.
+ int output_suppression_flags_;
+
DISALLOW_COPY_AND_ASSIGN(Representation);
};
diff --git a/packager/mpd/base/mpd_builder_unittest.cc b/packager/mpd/base/mpd_builder_unittest.cc
index f4ca90a6bf..4932ea3c8a 100644
--- a/packager/mpd/base/mpd_builder_unittest.cc
+++ b/packager/mpd/base/mpd_builder_unittest.cc
@@ -110,6 +110,8 @@ class MpdBuilderTest : public ::testing::Test {
}
protected:
+ // Creates a new AdaptationSet and adds a Representation element using
+ // |media_info|.
void AddRepresentation(const MediaInfo& media_info) {
AdaptationSet* adaptation_set = mpd_.AddAdaptationSet("");
ASSERT_TRUE(adaptation_set);
@@ -261,8 +263,7 @@ class SegmentTemplateTest : public DynamicMpdBuilderTest {
" frameRate=\"10/5\" contentType=\"video\""
" par=\"3:2\" segmentAlignment=\"true\">\n"
" \n"
+ " codecs=\"avc1.010101\" mimeType=\"video/mp4\" sar=\"1:1\">\n"
" \n"
" \n%s"
@@ -347,13 +348,12 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
" frameRate=\"10/2\" contentType=\"video\""
" par=\"3:2\" segmentAlignment=\"true\">\n"
" \n"
+ " codecs=\"avc1.010101\" mimeType=\"video/mp4\" sar=\"1:1\">\n"
" \n"
+ " initialization=\"init.mp4\" media=\"$Number$.mp4\" "
+ " startNumber=\"%d\">\n"
" \n"
- " %s\n"
+ " %s\n"
" \n"
" \n"
" \n"
@@ -1103,6 +1103,147 @@ TEST_F(CommonMpdBuilderTest,
ExpectAttributeNotSet("frameRate", adaptation_set_xml.get()));
}
+// Verify that Suppress*() methods work.
+TEST_F(CommonMpdBuilderTest, SuppressRepresentationAttributes) {
+ const char kTestMediaInfo[] =
+ "video_info {\n"
+ " codec: 'avc1'\n"
+ " width: 720\n"
+ " height: 480\n"
+ " time_scale: 10\n"
+ " frame_duration: 10\n"
+ " pixel_width: 1\n"
+ " pixel_height: 1\n"
+ "}\n"
+ "container_type: 1\n";
+
+ auto representation =
+ CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
+ kAnyRepresentationId, NoListener());
+
+ representation->SuppressOnce(Representation::kSuppressWidth);
+ xml::scoped_xml_ptr no_width(representation->GetXml());
+ EXPECT_NO_FATAL_FAILURE(ExpectAttributeNotSet("width", no_width.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("height", "480", no_width.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("frameRate", "10/10", no_width.get()));
+
+ representation->SuppressOnce(Representation::kSuppressHeight);
+ xml::scoped_xml_ptr no_height(representation->GetXml());
+ EXPECT_NO_FATAL_FAILURE(ExpectAttributeNotSet("height", no_height.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("width", "720", no_height.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("frameRate", "10/10", no_height.get()));
+
+ representation->SuppressOnce(Representation::kSuppressFrameRate);
+ xml::scoped_xml_ptr no_frame_rate(representation->GetXml());
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeNotSet("frameRate", no_frame_rate.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("width", "720", no_frame_rate.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("height", "480", no_frame_rate.get()));
+}
+
+// Attribute values that are common to all the children Representations should
+// propagate up to AdaptationSet. Otherwise, each Representation should have
+// its own values.
+TEST_F(CommonMpdBuilderTest, BubbleUpAttributesToAdaptationSet) {
+ const char k1080p[] =
+ "video_info {\n"
+ " codec: 'avc1'\n"
+ " width: 1920\n"
+ " height: 1080\n"
+ " time_scale: 30\n"
+ " frame_duration: 1\n"
+ " pixel_width: 1\n"
+ " pixel_height: 1\n"
+ "}\n"
+ "container_type: 1\n";
+
+ // Different width from the one above.
+ const char kDifferentWidth[] =
+ "video_info {\n"
+ " codec: 'avc1'\n"
+ " width: 1080\n"
+ " height: 1080\n"
+ " time_scale: 30\n"
+ " frame_duration: 1\n"
+ " pixel_width: 1\n"
+ " pixel_height: 1\n"
+ "}\n"
+ "container_type: 1\n";
+
+ // Different height from ones above
+ const char kDifferentHeight[] =
+ "video_info {\n"
+ " codec: 'avc1'\n"
+ " width: 1440\n"
+ " height: 900\n"
+ " time_scale: 30\n"
+ " frame_duration: 1\n"
+ " pixel_width: 1\n"
+ " pixel_height: 1\n"
+ "}\n"
+ "container_type: 1\n";
+
+ const char kDifferentFrameRate[] =
+ "video_info {\n"
+ " codec: 'avc1'\n"
+ " width: 1920\n"
+ " height: 1080\n"
+ " time_scale: 15\n"
+ " frame_duration: 1\n"
+ " pixel_width: 1\n"
+ " pixel_height: 1\n"
+ "}\n"
+ "container_type: 1\n";
+
+ AdaptationSet* adaptation_set = mpd_.AddAdaptationSet("");
+ ASSERT_TRUE(adaptation_set);
+ ASSERT_TRUE(adaptation_set->AddRepresentation(ConvertToMediaInfo(k1080p)));
+
+ xml::scoped_xml_ptr all_attributes_on_adaptation_set(
+ adaptation_set->GetXml());
+ EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
+ "width", "1920", all_attributes_on_adaptation_set.get()));
+ EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
+ "height", "1080", all_attributes_on_adaptation_set.get()));
+ EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
+ "frameRate", "30/1", all_attributes_on_adaptation_set.get()));
+
+ ASSERT_TRUE(
+ adaptation_set->AddRepresentation(ConvertToMediaInfo(kDifferentWidth)));
+ xml::scoped_xml_ptr width_not_set(adaptation_set->GetXml());
+ EXPECT_NO_FATAL_FAILURE(ExpectAttributeNotSet("width", width_not_set.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("height", "1080", width_not_set.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("frameRate", "30/1", width_not_set.get()));
+
+ ASSERT_TRUE(
+ adaptation_set->AddRepresentation(ConvertToMediaInfo(kDifferentHeight)));
+ xml::scoped_xml_ptr width_height_not_set(adaptation_set->GetXml());
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeNotSet("width", width_height_not_set.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeNotSet("height", width_height_not_set.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeEqString("frameRate", "30/1", width_height_not_set.get()));
+
+ ASSERT_TRUE(adaptation_set->AddRepresentation(
+ ConvertToMediaInfo(kDifferentFrameRate)));
+ xml::scoped_xml_ptr no_common_attributes(adaptation_set->GetXml());
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeNotSet("width", no_common_attributes.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeNotSet("height", no_common_attributes.get()));
+ EXPECT_NO_FATAL_FAILURE(
+ ExpectAttributeNotSet("frameRate", no_common_attributes.get()));
+}
+
// Verify that subsegmentAlignment is set to true if all the Representations'
// segments are aligned and the MPD type is static.
// Also checking that not all Representations have to be added before calling
@@ -1454,8 +1595,7 @@ TEST_F(CommonMpdBuilderTest, AdaptationSetAddContentProtectionAndUpdate) {
" any value"
" "
" "
+ " mimeType=\"video/mp4\"/>"
" "
" "
"";
@@ -1487,8 +1627,7 @@ TEST_F(CommonMpdBuilderTest, AdaptationSetAddContentProtectionAndUpdate) {
//" new pssh value"
" "
" "
+ " mimeType=\"video/mp4\"/>"
" "
" "
"";
@@ -1539,8 +1678,7 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
" value=\"some value\">"
" "
" "
+ " mimeType=\"video/mp4\"/>"
" "
" "
"";
@@ -1573,8 +1711,7 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
//" added pssh value"
" "
" "
+ " mimeType=\"video/mp4\"/>"
" "
" "
"";
@@ -1589,6 +1726,18 @@ TEST_F(StaticMpdBuilderTest, Video) {
EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputVideo1));
}
+TEST_F(StaticMpdBuilderTest, TwoVideosWithDifferentResolutions) {
+ AdaptationSet* adaptation_set = mpd_.AddAdaptationSet("");
+
+ MediaInfo media_info1 = GetTestMediaInfo(kFileNameVideoMediaInfo1);
+ ASSERT_TRUE(adaptation_set->AddRepresentation(media_info1));
+
+ MediaInfo media_info2 = GetTestMediaInfo(kFileNameVideoMediaInfo2);
+ ASSERT_TRUE(adaptation_set->AddRepresentation(media_info2));
+
+ EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputVideo1And2));
+}
+
// Add both video and audio and check the output.
TEST_F(StaticMpdBuilderTest, VideoAndAudio) {
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
diff --git a/packager/mpd/base/xml/xml_node.cc b/packager/mpd/base/xml/xml_node.cc
index 6480259b47..7e2b1e66b7 100644
--- a/packager/mpd/base/xml/xml_node.cc
+++ b/packager/mpd/base/xml/xml_node.cc
@@ -215,7 +215,10 @@ RepresentationXmlNode::RepresentationXmlNode()
: RepresentationBaseXmlNode("Representation") {}
RepresentationXmlNode::~RepresentationXmlNode() {}
-bool RepresentationXmlNode::AddVideoInfo(const VideoInfo& video_info) {
+bool RepresentationXmlNode::AddVideoInfo(const VideoInfo& video_info,
+ bool set_width,
+ bool set_height,
+ bool set_frame_rate) {
if (!video_info.has_width() || !video_info.has_height()) {
LOG(ERROR) << "Missing width or height for adding a video info.";
return false;
@@ -227,11 +230,15 @@ bool RepresentationXmlNode::AddVideoInfo(const VideoInfo& video_info) {
base::IntToString(video_info.pixel_height()));
}
- SetIntegerAttribute("width", video_info.width());
- SetIntegerAttribute("height", video_info.height());
- SetStringAttribute("frameRate",
- base::IntToString(video_info.time_scale()) + "/" +
- base::IntToString(video_info.frame_duration()));
+ if (set_width)
+ SetIntegerAttribute("width", video_info.width());
+ if (set_height)
+ SetIntegerAttribute("height", video_info.height());
+ if (set_frame_rate) {
+ SetStringAttribute("frameRate",
+ base::IntToString(video_info.time_scale()) + "/" +
+ base::IntToString(video_info.frame_duration()));
+ }
return true;
}
diff --git a/packager/mpd/base/xml/xml_node.h b/packager/mpd/base/xml/xml_node.h
index 39c7266169..e0d481ef97 100644
--- a/packager/mpd/base/xml/xml_node.h
+++ b/packager/mpd/base/xml/xml_node.h
@@ -132,9 +132,15 @@ class RepresentationXmlNode : public RepresentationBaseXmlNode {
/// Adds video metadata to the MPD.
/// @param video_info constains the VideoInfo for a Representation.
+ /// @param set_width is a flag for setting the width attribute.
+ /// @param set_height is a flag for setting the height attribute.
+ /// @param set_frame_rate is a flag for setting the frameRate attribute.
/// @return true if successfully set attributes and children elements (if
/// applicable), false otherwise.
- bool AddVideoInfo(const MediaInfo::VideoInfo& video_info);
+ bool AddVideoInfo(const MediaInfo::VideoInfo& video_info,
+ bool set_width,
+ bool set_height,
+ bool set_frame_rate);
/// Adds audio metadata to the MPD.
/// @param audio_info constains the AudioInfos for a Representation.
diff --git a/packager/mpd/test/data/audio_media_info1_video_media_info1_expected_mpd_output.txt b/packager/mpd/test/data/audio_media_info1_video_media_info1_expected_mpd_output.txt
index a058d16dec..587ccaa537 100644
--- a/packager/mpd/test/data/audio_media_info1_video_media_info1_expected_mpd_output.txt
+++ b/packager/mpd/test/data/audio_media_info1_video_media_info1_expected_mpd_output.txt
@@ -2,7 +2,7 @@
-
+
test_output_file_name1.mp4
diff --git a/packager/mpd/test/data/dynamic_normal_mpd.txt b/packager/mpd/test/data/dynamic_normal_mpd.txt
index c15790b1b3..075c9e53ac 100644
--- a/packager/mpd/test/data/dynamic_normal_mpd.txt
+++ b/packager/mpd/test/data/dynamic_normal_mpd.txt
@@ -2,7 +2,7 @@
-
+
diff --git a/packager/mpd/test/data/language_audio_media_info_expected_output.txt b/packager/mpd/test/data/language_audio_media_info_expected_output.txt
index 1e6aa020cd..68dd6b8afc 100644
--- a/packager/mpd/test/data/language_audio_media_info_expected_output.txt
+++ b/packager/mpd/test/data/language_audio_media_info_expected_output.txt
@@ -2,7 +2,7 @@
-
+
test_output_file_name1.mp4
diff --git a/packager/mpd/test/data/video_media_info1_expected_mpd_output.txt b/packager/mpd/test/data/video_media_info1_expected_mpd_output.txt
index c0411ce5ec..d5c4429555 100644
--- a/packager/mpd/test/data/video_media_info1_expected_mpd_output.txt
+++ b/packager/mpd/test/data/video_media_info1_expected_mpd_output.txt
@@ -2,7 +2,7 @@
-
+
test_output_file_name1.mp4