max{Width,Height,FrameRate} for AdaptationSet
- DASH IOP requires AdaptationSets with video Representations to have: @maxWidth (or @width if all the Representations have the same width). @maxHeight (or @height if all the Representations have the same width). @maxFrameRate (or @frameRate if all the Representations have the same frame rate). Change-Id: I1247b7461237255aeb70b7fb40f78d4439f9c529
This commit is contained in:
parent
d685edef62
commit
a02e3b60df
|
@ -526,6 +526,23 @@ Representation* AdaptationSet::AddRepresentation(const MediaInfo& media_info) {
|
||||||
if (!representation->Init())
|
if (!representation->Init())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// For videos, record the width, height, and the frame rate to calculate the
|
||||||
|
// max {width,height,framerate} required for DASH IOP.
|
||||||
|
if(media_info.video_info_size() > 0) {
|
||||||
|
const MediaInfo::VideoInfo& video_info = media_info.video_info(0);
|
||||||
|
DCHECK(video_info.has_width());
|
||||||
|
DCHECK(video_info.has_height());
|
||||||
|
video_widths_.insert(video_info.width());
|
||||||
|
video_heights_.insert(video_info.height());
|
||||||
|
|
||||||
|
if (video_info.has_time_scale() && video_info.has_frame_duration()) {
|
||||||
|
video_frame_rates_[static_cast<double>(video_info.time_scale()) /
|
||||||
|
video_info.frame_duration()] =
|
||||||
|
base::IntToString(video_info.time_scale()) + "/" +
|
||||||
|
base::IntToString(video_info.frame_duration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
representations_.push_back(representation.get());
|
representations_.push_back(representation.get());
|
||||||
return representation.release();
|
return representation.release();
|
||||||
}
|
}
|
||||||
|
@ -553,7 +570,7 @@ xml::ScopedXmlPtr<xmlNode>::type AdaptationSet::GetXml() {
|
||||||
|
|
||||||
for (; representation_it != representations_.end(); ++representation_it) {
|
for (; representation_it != representations_.end(); ++representation_it) {
|
||||||
xml::ScopedXmlPtr<xmlNode>::type child((*representation_it)->GetXml());
|
xml::ScopedXmlPtr<xmlNode>::type child((*representation_it)->GetXml());
|
||||||
if (!child.get() || !adaptation_set.AddChild(child.Pass()))
|
if (!child || !adaptation_set.AddChild(child.Pass()))
|
||||||
return xml::ScopedXmlPtr<xmlNode>::type();
|
return xml::ScopedXmlPtr<xmlNode>::type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,6 +578,26 @@ xml::ScopedXmlPtr<xmlNode>::type AdaptationSet::GetXml() {
|
||||||
if (!lang_.empty() && lang_ != "und") {
|
if (!lang_.empty() && lang_ != "und") {
|
||||||
adaptation_set.SetStringAttribute("lang", LanguageToShortestForm(lang_));
|
adaptation_set.SetStringAttribute("lang", LanguageToShortestForm(lang_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that std::{set,map} are ordered, so the last element is the max value.
|
||||||
|
if (video_widths_.size() == 1) {
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
adaptation_set.SetStringAttribute("frameRate",
|
||||||
|
video_frame_rates_.begin()->second);
|
||||||
|
} else if (video_frame_rates_.size() > 1) {
|
||||||
|
adaptation_set.SetStringAttribute("maxFrameRate",
|
||||||
|
video_frame_rates_.rbegin()->second);
|
||||||
|
}
|
||||||
return adaptation_set.PassScopedPtr();
|
return adaptation_set.PassScopedPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "packager/base/atomic_sequence_num.h"
|
#include "packager/base/atomic_sequence_num.h"
|
||||||
|
@ -204,6 +206,20 @@ class AdaptationSet {
|
||||||
const std::string lang_;
|
const std::string lang_;
|
||||||
const MpdOptions& mpd_options_;
|
const MpdOptions& mpd_options_;
|
||||||
|
|
||||||
|
// Video widths and heights of Representations. Note that this is a set; if
|
||||||
|
// there is only 1 resolution, then @width & @height should be set, otherwise
|
||||||
|
// @maxWidth & @maxHeight should be set for DASH IOP.
|
||||||
|
std::set<uint32_t> video_widths_;
|
||||||
|
std::set<uint32_t> video_heights_;
|
||||||
|
|
||||||
|
// Video representations' frame rates.
|
||||||
|
// The frame rate notation for MPD is <integer>/<integer> (where the
|
||||||
|
// denominator is optional). This means the frame rate could be non-whole
|
||||||
|
// rational value, therefore the key is of type double.
|
||||||
|
// Value is <integer>/<integer> in string form.
|
||||||
|
// So, key == CalculatedValue(value)
|
||||||
|
std::map<double, std::string> video_frame_rates_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AdaptationSet);
|
DISALLOW_COPY_AND_ASSIGN(AdaptationSet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -60,15 +60,22 @@ void CheckIdEqual(uint32_t expected_id, T* node) {
|
||||||
ASSERT_NO_FATAL_FAILURE(ExpectXmlElementIdEqual(node_xml.get(), expected_id));
|
ASSERT_NO_FATAL_FAILURE(ExpectXmlElementIdEqual(node_xml.get(), expected_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectAttributeHasString(base::StringPiece attribute,
|
void ExpectAttributeEqString(base::StringPiece attribute,
|
||||||
base::StringPiece expected_value,
|
base::StringPiece expected_value,
|
||||||
xmlNodePtr node) {
|
xmlNodePtr node) {
|
||||||
xml::ScopedXmlPtr<xmlChar>::type attribute_xml_str(
|
xml::ScopedXmlPtr<xmlChar>::type attribute_xml_str(
|
||||||
xmlGetProp(node, BAD_CAST attribute.data()));
|
xmlGetProp(node, BAD_CAST attribute.data()));
|
||||||
ASSERT_TRUE(attribute_xml_str);
|
ASSERT_TRUE(attribute_xml_str);
|
||||||
EXPECT_STREQ(expected_value.data(),
|
EXPECT_STREQ(expected_value.data(),
|
||||||
reinterpret_cast<const char*>(attribute_xml_str.get()));
|
reinterpret_cast<const char*>(attribute_xml_str.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// |attribute| should not be set in |node|.
|
||||||
|
void ExpectAttributeNotSet(base::StringPiece attribute, xmlNodePtr node) {
|
||||||
|
xml::ScopedXmlPtr<xmlChar>::type attribute_xml_str(
|
||||||
|
xmlGetProp(node, BAD_CAST attribute.data()));
|
||||||
|
ASSERT_FALSE(attribute_xml_str);
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template <MpdBuilder::MpdType type>
|
template <MpdBuilder::MpdType type>
|
||||||
|
@ -200,7 +207,8 @@ class SegmentTemplateTest : public DynamicMpdBuilderTest {
|
||||||
"availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
|
"availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
|
||||||
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\">\n"
|
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\">\n"
|
||||||
" <Period start=\"PT0S\">\n"
|
" <Period start=\"PT0S\">\n"
|
||||||
" <AdaptationSet id=\"0\">\n"
|
" <AdaptationSet id=\"0\" width=\"720\" height=\"480\""
|
||||||
|
" frameRate=\"10/5\">\n"
|
||||||
" <Representation id=\"0\" bandwidth=\"%" PRIu64 "\" "
|
" <Representation id=\"0\" bandwidth=\"%" PRIu64 "\" "
|
||||||
"codecs=\"avc1.010101\" mimeType=\"video/mp4\" width=\"720\" "
|
"codecs=\"avc1.010101\" mimeType=\"video/mp4\" width=\"720\" "
|
||||||
"height=\"480\" frameRate=\"10/5\" sar=\"1:1\">\n"
|
"height=\"480\" frameRate=\"10/5\" sar=\"1:1\">\n"
|
||||||
|
@ -282,7 +290,8 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
|
||||||
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
||||||
"timeShiftBufferDepth=\"PT%dS\">\n"
|
"timeShiftBufferDepth=\"PT%dS\">\n"
|
||||||
" <Period start=\"PT0S\">\n"
|
" <Period start=\"PT0S\">\n"
|
||||||
" <AdaptationSet id=\"0\">\n"
|
" <AdaptationSet id=\"0\" width=\"720\" height=\"480\""
|
||||||
|
" frameRate=\"10/2\">\n"
|
||||||
" <Representation id=\"0\" bandwidth=\"%" PRIu64 "\" "
|
" <Representation id=\"0\" bandwidth=\"%" PRIu64 "\" "
|
||||||
"codecs=\"avc1.010101\" mimeType=\"video/mp4\" width=\"720\" "
|
"codecs=\"avc1.010101\" mimeType=\"video/mp4\" width=\"720\" "
|
||||||
"height=\"480\" frameRate=\"10/2\" sar=\"1:1\">\n"
|
"height=\"480\" frameRate=\"10/2\" sar=\"1:1\">\n"
|
||||||
|
@ -366,29 +375,221 @@ TEST_F(CommonMpdBuilderTest, CheckVideoInfoReflectedInXml) {
|
||||||
Representation representation(
|
Representation representation(
|
||||||
ConvertToMediaInfo(kTestMediaInfo), MpdOptions(), kAnyRepresentationId);
|
ConvertToMediaInfo(kTestMediaInfo), MpdOptions(), kAnyRepresentationId);
|
||||||
EXPECT_TRUE(representation.Init());
|
EXPECT_TRUE(representation.Init());
|
||||||
|
|
||||||
xml::ScopedXmlPtr<xmlNode>::type node_xml(representation.GetXml());
|
xml::ScopedXmlPtr<xmlNode>::type node_xml(representation.GetXml());
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
ExpectAttributeHasString("codecs", "avc1", node_xml.get()));
|
ExpectAttributeEqString("codecs", "avc1", node_xml.get()));
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
ExpectAttributeHasString("width", "1280", node_xml.get()));
|
ExpectAttributeEqString("width", "1280", node_xml.get()));
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
ExpectAttributeHasString("height", "720", node_xml.get()));
|
ExpectAttributeEqString("height", "720", node_xml.get()));
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
ExpectAttributeHasString("sar", "1:1", node_xml.get()));
|
ExpectAttributeEqString("sar", "1:1", node_xml.get()));
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
ExpectAttributeHasString("frameRate", "10/10", node_xml.get()));
|
ExpectAttributeEqString("frameRate", "10/10", node_xml.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CommonMpdBuilderTest, CheckAdaptationSetId) {
|
TEST_F(CommonMpdBuilderTest, CheckAdaptationSetId) {
|
||||||
base::AtomicSequenceNumber sequence_counter;
|
base::AtomicSequenceNumber sequence_counter;
|
||||||
const uint32_t kAdaptationSetId = 42;
|
const uint32_t kAdaptationSetId = 42;
|
||||||
|
|
||||||
AdaptationSet adaptation_set(
|
AdaptationSet adaptation_set(
|
||||||
kAdaptationSetId, "", MpdOptions(), &sequence_counter);
|
kAdaptationSetId, "", MpdOptions(), &sequence_counter);
|
||||||
ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kAdaptationSetId, &adaptation_set));
|
ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kAdaptationSetId, &adaptation_set));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that if all video Representations in an AdaptationSet have the same
|
||||||
|
// frame rate, AdaptationSet also has a frameRate attribute.
|
||||||
|
TEST_F(CommonMpdBuilderTest, AdapatationSetFrameRate) {
|
||||||
|
const char kVideoMediaInfo1[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 720\n"
|
||||||
|
" height: 480\n"
|
||||||
|
" time_scale: 10\n"
|
||||||
|
" frame_duration: 3\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
const char kVideoMediaInfo2[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 720\n"
|
||||||
|
" height: 480\n"
|
||||||
|
" time_scale: 10\n"
|
||||||
|
" frame_duration: 3\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo1)));
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo2)));
|
||||||
|
|
||||||
|
xml::ScopedXmlPtr<xmlNode>::type adaptation_set_xml(
|
||||||
|
video_adaptation_set->GetXml());
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeEqString("frameRate", "10/3", adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("maxFrameRate", adaptation_set_xml.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that if there are videos with different frame rates, the maxFrameRate
|
||||||
|
// is set.
|
||||||
|
TEST_F(CommonMpdBuilderTest, AdapatationSetMaxFrameRate) {
|
||||||
|
// 30fps video.
|
||||||
|
const char kVideoMediaInfo30fps[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 720\n"
|
||||||
|
" height: 480\n"
|
||||||
|
" time_scale: 3000\n"
|
||||||
|
" frame_duration: 100\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
const char kVideoMediaInfo15fps[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 720\n"
|
||||||
|
" height: 480\n"
|
||||||
|
" time_scale: 3000\n"
|
||||||
|
" frame_duration: 200\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo30fps)));
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo15fps)));
|
||||||
|
|
||||||
|
xml::ScopedXmlPtr<xmlNode>::type adaptation_set_xml(
|
||||||
|
video_adaptation_set->GetXml());
|
||||||
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString("maxFrameRate", "3000/100",
|
||||||
|
adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("frameRate", adaptation_set_xml.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch the case where it ends up wrong if integer division is used to check
|
||||||
|
// the frame rate.
|
||||||
|
// IOW, A/B != C/D but when using integer division A/B == C/D.
|
||||||
|
// SO, maxFrameRate should be set instead of frameRate.
|
||||||
|
TEST_F(CommonMpdBuilderTest,
|
||||||
|
AdapatationSetMaxFrameRateIntegerDivisionEdgeCase) {
|
||||||
|
// 11/3 != 10/3 but IntegerDiv(11,3) == IntegerDiv(10,3).
|
||||||
|
const char kVideoMediaInfo1[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 720\n"
|
||||||
|
" height: 480\n"
|
||||||
|
" time_scale: 11\n"
|
||||||
|
" frame_duration: 3\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
const char kVideoMediaInfo2[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 720\n"
|
||||||
|
" height: 480\n"
|
||||||
|
" time_scale: 10\n"
|
||||||
|
" frame_duration: 3\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo1)));
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo2)));
|
||||||
|
|
||||||
|
xml::ScopedXmlPtr<xmlNode>::type adaptation_set_xml(
|
||||||
|
video_adaptation_set->GetXml());
|
||||||
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString("maxFrameRate", "11/3",
|
||||||
|
adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("frameRate", adaptation_set_xml.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the width and height attribute are set if all the video
|
||||||
|
// representations have the same width and height.
|
||||||
|
TEST_F(StaticMpdBuilderTest, AdapatationSetWidthAndHeight) {
|
||||||
|
// Both 720p.
|
||||||
|
const char kVideoMediaInfo1[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 1280\n"
|
||||||
|
" height: 720\n"
|
||||||
|
" time_scale: 3000\n"
|
||||||
|
" frame_duration: 100\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
const char kVideoMediaInfo2[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 1280\n"
|
||||||
|
" height: 720\n"
|
||||||
|
" time_scale: 3000\n"
|
||||||
|
" frame_duration: 200\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo1)));
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo2)));
|
||||||
|
|
||||||
|
xml::ScopedXmlPtr<xmlNode>::type adaptation_set_xml(
|
||||||
|
video_adaptation_set->GetXml());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeEqString("width", "1280", adaptation_set_xml.get()));
|
||||||
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeEqString("height", "720", adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("maxWidth", adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("maxHeight", adaptation_set_xml.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the maxWidth and maxHeight attribute are set if there are
|
||||||
|
// multiple video resolutions.
|
||||||
|
TEST_F(StaticMpdBuilderTest, AdapatationSetMaxWidthAndMaxHeight) {
|
||||||
|
const char kVideoMediaInfo1080p[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 1920\n"
|
||||||
|
" height: 1080\n"
|
||||||
|
" time_scale: 3000\n"
|
||||||
|
" frame_duration: 100\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
const char kVideoMediaInfo720p[] =
|
||||||
|
"video_info {\n"
|
||||||
|
" codec: \"avc1\"\n"
|
||||||
|
" width: 1280\n"
|
||||||
|
" height: 720\n"
|
||||||
|
" time_scale: 3000\n"
|
||||||
|
" frame_duration: 100\n"
|
||||||
|
"}\n"
|
||||||
|
"container_type: 1\n";
|
||||||
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo1080p)));
|
||||||
|
ASSERT_TRUE(video_adaptation_set->AddRepresentation(
|
||||||
|
ConvertToMediaInfo(kVideoMediaInfo720p)));
|
||||||
|
|
||||||
|
xml::ScopedXmlPtr<xmlNode>::type adaptation_set_xml(
|
||||||
|
video_adaptation_set->GetXml());
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeEqString("maxWidth", "1920", adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeEqString("maxHeight", "1080", adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("width", adaptation_set_xml.get()));
|
||||||
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
ExpectAttributeNotSet("height", adaptation_set_xml.get()));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CommonMpdBuilderTest, CheckRepresentationId) {
|
TEST_F(CommonMpdBuilderTest, CheckRepresentationId) {
|
||||||
const MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
const MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
const uint32_t kRepresentationId = 1;
|
const uint32_t kRepresentationId = 1;
|
||||||
|
|
|
@ -47,7 +47,7 @@ class XmlNode {
|
||||||
void SetStringAttribute(const char* attribute_name,
|
void SetStringAttribute(const char* attribute_name,
|
||||||
const std::string& attribute);
|
const std::string& attribute);
|
||||||
|
|
||||||
/// Sets an interger attribute.
|
/// Sets an integer attribute.
|
||||||
/// @param attribute_name The name (lhs) of the attribute.
|
/// @param attribute_name The name (lhs) of the attribute.
|
||||||
/// @param number The value (rhs) of the attribute.
|
/// @param number The value (rhs) of the attribute.
|
||||||
void SetIntegerAttribute(const char* attribute_name, uint64_t number);
|
void SetIntegerAttribute(const char* attribute_name, uint64_t number);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
||||||
<Period>
|
<Period>
|
||||||
<AdaptationSet id="0">
|
<AdaptationSet id="0" width="720" height="480" frameRate="10/1">
|
||||||
<Representation id="1" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
<Representation id="1" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
||||||
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="121-221" timescale="1000">
|
<SegmentBase indexRange="121-221" timescale="1000">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" availabilityStartTime="2011-12-25T12:30:00" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011">
|
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" availabilityStartTime="2011-12-25T12:30:00" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011">
|
||||||
<Period start="PT0S">
|
<Period start="PT0S">
|
||||||
<AdaptationSet id="0">
|
<AdaptationSet id="0" width="720" height="480" frameRate="10/5">
|
||||||
<Representation id="0" bandwidth="102400" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/5" sar="1:1">
|
<Representation id="0" bandwidth="102400" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/5" sar="1:1">
|
||||||
<SegmentTemplate timescale="1000" initialization="init.mp4" media="$Time$.mp4">
|
<SegmentTemplate timescale="1000" initialization="init.mp4" media="$Time$.mp4">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
||||||
<Period>
|
<Period>
|
||||||
<AdaptationSet id="0">
|
<AdaptationSet id="0" width="720" height="480" frameRate="10/1">
|
||||||
<Representation id="3" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
<Representation id="3" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
||||||
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="121-221" timescale="1000">
|
<SegmentBase indexRange="121-221" timescale="1000">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
||||||
<Period>
|
<Period>
|
||||||
<AdaptationSet id="0">
|
<AdaptationSet id="0" width="720" height="480" frameRate="10/1">
|
||||||
<Representation id="0" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
<Representation id="0" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
||||||
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="121-221" timescale="1000">
|
<SegmentBase indexRange="121-221" timescale="1000">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
|
||||||
<Period>
|
<Period>
|
||||||
<AdaptationSet id="0">
|
<AdaptationSet id="0" maxWidth="720" maxHeight="480" maxFrameRate="10/1">
|
||||||
<Representation id="0" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
<Representation id="0" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
|
||||||
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
<BaseURL>test_output_file_name1.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="121-221" timescale="1000">
|
<SegmentBase indexRange="121-221" timescale="1000">
|
||||||
|
|
Loading…
Reference in New Issue