Part one of supporting live profile with static mpd
- Added two new fields in MpdOptions: dash_profile and mpd_type - Updated MpdBuilder to support LiveProfile with static mpd - Command line arguments will be updated in the next CL Issue #142 Change-Id: Ibd35e5c9e1b1ef98043392e3f04a0af4700135c1
This commit is contained in:
parent
ce23fbacc4
commit
5aaae303e8
|
@ -460,16 +460,14 @@ bool RunPackager(const StreamDescriptorList& stream_descriptors) {
|
||||||
|
|
||||||
std::unique_ptr<MpdNotifier> mpd_notifier;
|
std::unique_ptr<MpdNotifier> mpd_notifier;
|
||||||
if (!FLAGS_mpd_output.empty()) {
|
if (!FLAGS_mpd_output.empty()) {
|
||||||
DashProfile profile =
|
|
||||||
FLAGS_single_segment ? kOnDemandProfile : kLiveProfile;
|
|
||||||
std::vector<std::string> base_urls = base::SplitString(
|
std::vector<std::string> base_urls = base::SplitString(
|
||||||
FLAGS_base_urls, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
FLAGS_base_urls, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||||
if (FLAGS_generate_dash_if_iop_compliant_mpd) {
|
if (FLAGS_generate_dash_if_iop_compliant_mpd) {
|
||||||
mpd_notifier.reset(new DashIopMpdNotifier(profile, mpd_options, base_urls,
|
mpd_notifier.reset(
|
||||||
FLAGS_mpd_output));
|
new DashIopMpdNotifier(mpd_options, base_urls, FLAGS_mpd_output));
|
||||||
} else {
|
} else {
|
||||||
mpd_notifier.reset(new SimpleMpdNotifier(profile, mpd_options, base_urls,
|
mpd_notifier.reset(
|
||||||
FLAGS_mpd_output));
|
new SimpleMpdNotifier(mpd_options, base_urls, FLAGS_mpd_output));
|
||||||
}
|
}
|
||||||
if (!mpd_notifier->Init()) {
|
if (!mpd_notifier->Init()) {
|
||||||
LOG(ERROR) << "MpdNotifier failed to initialize.";
|
LOG(ERROR) << "MpdNotifier failed to initialize.";
|
||||||
|
|
|
@ -171,6 +171,12 @@ bool GetMuxerOptions(MuxerOptions* muxer_options) {
|
||||||
bool GetMpdOptions(MpdOptions* mpd_options) {
|
bool GetMpdOptions(MpdOptions* mpd_options) {
|
||||||
DCHECK(mpd_options);
|
DCHECK(mpd_options);
|
||||||
|
|
||||||
|
mpd_options->dash_profile =
|
||||||
|
FLAGS_single_segment ? DashProfile::kOnDemand : DashProfile::kLive;
|
||||||
|
// Single segment does not always mean static mpd.
|
||||||
|
// TODO(kqyang): Add a new flag for mpd type and update the code.
|
||||||
|
mpd_options->mpd_type =
|
||||||
|
FLAGS_single_segment ? MpdType::kStatic : MpdType::kDynamic;
|
||||||
mpd_options->availability_time_offset = FLAGS_availability_time_offset;
|
mpd_options->availability_time_offset = FLAGS_availability_time_offset;
|
||||||
mpd_options->minimum_update_period = FLAGS_minimum_update_period;
|
mpd_options->minimum_update_period = FLAGS_minimum_update_period;
|
||||||
mpd_options->min_buffer_time = FLAGS_min_buffer_time;
|
mpd_options->min_buffer_time = FLAGS_min_buffer_time;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.781S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.781S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="audio" subsegmentAlignment="true">
|
<AdaptationSet id="0" contentType="audio" subsegmentAlignment="true">
|
||||||
<Representation id="0" bandwidth="81545" codecs="opus" mimeType="audio/mp4" audioSamplingRate="48000">
|
<Representation id="0" bandwidth="81545" codecs="opus" mimeType="audio/mp4" audioSamplingRate="48000">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.768S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.768S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="audio">
|
<AdaptationSet id="0" contentType="audio">
|
||||||
<Representation id="0" bandwidth="69362" codecs="vorbis" mimeType="audio/webm" audioSamplingRate="44100">
|
<Representation id="0" bandwidth="69362" codecs="vorbis" mimeType="audio/webm" audioSamplingRate="44100">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.781S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.781S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="audio">
|
<AdaptationSet id="0" contentType="audio">
|
||||||
<Representation id="0" bandwidth="76531" codecs="opus" mimeType="audio/webm" audioSamplingRate="48000">
|
<Representation id="0" bandwidth="76531" codecs="opus" mimeType="audio/webm" audioSamplingRate="48000">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="885567" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="885567" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="884377" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="884377" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="885567" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="885567" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="885567" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="885567" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="882040" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="882040" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="875620" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="875620" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="876506" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="876506" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="00000000-0000-0000-0000-000000000000"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="872999" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="872999" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.76317S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.76317S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="text">
|
<AdaptationSet id="0" contentType="text">
|
||||||
<Representation id="0" bandwidth="256" mimeType="text/vtt">
|
<Representation id="0" bandwidth="256" mimeType="text/vtt">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.8028S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.8028S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="264870" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="264870" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.73607S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.73607S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="882040" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="882040" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.736S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.736S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" subsegmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" subsegmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="342199" codecs="vp08.00.00.08.01.01.00.00" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="342199" codecs="vp08.00.00.08.01.01.00.00" mimeType="video/mp4" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.736S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.736S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" par="16:9">
|
||||||
<Representation id="0" bandwidth="337062" codecs="vp8" mimeType="video/webm" sar="1:1">
|
<Representation id="0" bandwidth="337062" codecs="vp8" mimeType="video/webm" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT2.736S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.736S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" par="16:9">
|
||||||
<Representation id="0" bandwidth="335457" codecs="vp8" mimeType="video/webm" sar="1:1">
|
<Representation id="0" bandwidth="335457" codecs="vp8" mimeType="video/webm" sar="1:1">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||||
<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" xmlns:cenc="urn:mpeg:cenc:2013" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT0S">
|
<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" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT0S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="text">
|
<AdaptationSet id="0" contentType="text">
|
||||||
<Representation id="0" bandwidth="256" mimeType="text/vtt">
|
<Representation id="0" bandwidth="256" mimeType="text/vtt">
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace media {
|
||||||
MpdNotifyMuxerListener::MpdNotifyMuxerListener(MpdNotifier* mpd_notifier)
|
MpdNotifyMuxerListener::MpdNotifyMuxerListener(MpdNotifier* mpd_notifier)
|
||||||
: mpd_notifier_(mpd_notifier), notification_id_(0), is_encrypted_(false) {
|
: mpd_notifier_(mpd_notifier), notification_id_(0), is_encrypted_(false) {
|
||||||
DCHECK(mpd_notifier);
|
DCHECK(mpd_notifier);
|
||||||
DCHECK(mpd_notifier->dash_profile() == kOnDemandProfile ||
|
DCHECK(mpd_notifier->dash_profile() == DashProfile::kOnDemand ||
|
||||||
mpd_notifier->dash_profile() == kLiveProfile);
|
mpd_notifier->dash_profile() == DashProfile::kLive);
|
||||||
}
|
}
|
||||||
|
|
||||||
MpdNotifyMuxerListener::~MpdNotifyMuxerListener() {}
|
MpdNotifyMuxerListener::~MpdNotifyMuxerListener() {}
|
||||||
|
@ -76,7 +76,7 @@ void MpdNotifyMuxerListener::OnMediaStart(
|
||||||
key_system_info_, media_info.get());
|
key_system_info_, media_info.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpd_notifier_->dash_profile() == kLiveProfile) {
|
if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
|
||||||
// TODO(kqyang): Check return result.
|
// TODO(kqyang): Check return result.
|
||||||
mpd_notifier_->NotifyNewContainer(*media_info, ¬ification_id_);
|
mpd_notifier_->NotifyNewContainer(*media_info, ¬ification_id_);
|
||||||
} else {
|
} else {
|
||||||
|
@ -88,7 +88,7 @@ void MpdNotifyMuxerListener::OnMediaStart(
|
||||||
// the information is in the media info.
|
// the information is in the media info.
|
||||||
void MpdNotifyMuxerListener::OnSampleDurationReady(
|
void MpdNotifyMuxerListener::OnSampleDurationReady(
|
||||||
uint32_t sample_duration) {
|
uint32_t sample_duration) {
|
||||||
if (mpd_notifier_->dash_profile() == kLiveProfile) {
|
if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
|
||||||
mpd_notifier_->NotifySampleDuration(notification_id_, sample_duration);
|
mpd_notifier_->NotifySampleDuration(notification_id_, sample_duration);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,10 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
|
||||||
uint64_t index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64_t file_size) {
|
uint64_t file_size) {
|
||||||
if (mpd_notifier_->dash_profile() == kLiveProfile) {
|
if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
|
||||||
DCHECK(subsegments_.empty());
|
DCHECK(subsegments_.empty());
|
||||||
|
if (mpd_notifier_->mpd_type() == MpdType::kStatic)
|
||||||
|
mpd_notifier_->Flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,10 +154,11 @@ void MpdNotifyMuxerListener::OnNewSegment(const std::string& file_name,
|
||||||
uint64_t start_time,
|
uint64_t start_time,
|
||||||
uint64_t duration,
|
uint64_t duration,
|
||||||
uint64_t segment_file_size) {
|
uint64_t segment_file_size) {
|
||||||
if (mpd_notifier_->dash_profile() == kLiveProfile) {
|
if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
|
||||||
// TODO(kqyang): Check return result.
|
// TODO(kqyang): Check return result.
|
||||||
mpd_notifier_->NotifyNewSegment(
|
mpd_notifier_->NotifyNewSegment(
|
||||||
notification_id_, start_time, duration, segment_file_size);
|
notification_id_, start_time, duration, segment_file_size);
|
||||||
|
if (mpd_notifier_->mpd_type() == MpdType::kDynamic)
|
||||||
mpd_notifier_->Flush();
|
mpd_notifier_->Flush();
|
||||||
} else {
|
} else {
|
||||||
SubsegmentInfo subsegment = {start_time, duration, segment_file_size};
|
SubsegmentInfo subsegment = {start_time, duration, segment_file_size};
|
||||||
|
|
|
@ -64,17 +64,25 @@ const uint8_t kBogusIv[] = {
|
||||||
|
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
class MpdNotifyMuxerListenerTest : public ::testing::Test {
|
class MpdNotifyMuxerListenerTest : public ::testing::TestWithParam<MpdType> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void SetupForVod() {
|
void SetupForVod() {
|
||||||
notifier_.reset(new MockMpdNotifier(kOnDemandProfile));
|
MpdOptions mpd_options;
|
||||||
|
mpd_options.dash_profile = DashProfile::kOnDemand;
|
||||||
|
// On-demand profile should be static.
|
||||||
|
mpd_options.mpd_type = MpdType::kStatic;
|
||||||
|
notifier_.reset(new MockMpdNotifier(mpd_options));
|
||||||
listener_.reset(
|
listener_.reset(
|
||||||
new MpdNotifyMuxerListener(notifier_.get()));
|
new MpdNotifyMuxerListener(notifier_.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupForLive() {
|
void SetupForLive() {
|
||||||
notifier_.reset(new MockMpdNotifier(kLiveProfile));
|
MpdOptions mpd_options;
|
||||||
|
mpd_options.dash_profile = DashProfile::kLive;
|
||||||
|
// Live profile can be static or dynamic.
|
||||||
|
mpd_options.mpd_type = GetParam();
|
||||||
|
notifier_.reset(new MockMpdNotifier(mpd_options));
|
||||||
listener_.reset(new MpdNotifyMuxerListener(notifier_.get()));
|
listener_.reset(new MpdNotifyMuxerListener(notifier_.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +279,7 @@ TEST_F(MpdNotifyMuxerListenerTest, VodOnNewSegment) {
|
||||||
|
|
||||||
// Live without key rotation. Note that OnEncryptionInfoReady() is called before
|
// Live without key rotation. Note that OnEncryptionInfoReady() is called before
|
||||||
// OnMediaStart() but no more calls.
|
// OnMediaStart() but no more calls.
|
||||||
TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
|
TEST_P(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
|
||||||
SetupForLive();
|
SetupForLive();
|
||||||
MuxerOptions muxer_options;
|
MuxerOptions muxer_options;
|
||||||
SetDefaultLiveMuxerOptionsValues(&muxer_options);
|
SetDefaultLiveMuxerOptionsValues(&muxer_options);
|
||||||
|
@ -317,9 +325,12 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
|
||||||
.Times(1);
|
.Times(1);
|
||||||
EXPECT_CALL(*notifier_,
|
EXPECT_CALL(*notifier_,
|
||||||
NotifyNewSegment(_, kStartTime1, kDuration1, kSegmentFileSize1));
|
NotifyNewSegment(_, kStartTime1, kDuration1, kSegmentFileSize1));
|
||||||
|
// Flush should only be called once in OnMediaEnd.
|
||||||
|
if (GetParam() == MpdType::kDynamic)
|
||||||
EXPECT_CALL(*notifier_, Flush());
|
EXPECT_CALL(*notifier_, Flush());
|
||||||
EXPECT_CALL(*notifier_,
|
EXPECT_CALL(*notifier_,
|
||||||
NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2));
|
NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2));
|
||||||
|
if (GetParam() == MpdType::kDynamic)
|
||||||
EXPECT_CALL(*notifier_, Flush());
|
EXPECT_CALL(*notifier_, Flush());
|
||||||
|
|
||||||
std::vector<uint8_t> iv(kBogusIv, kBogusIv + arraysize(kBogusIv));
|
std::vector<uint8_t> iv(kBogusIv, kBogusIv + arraysize(kBogusIv));
|
||||||
|
@ -333,13 +344,14 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveNoKeyRotation) {
|
||||||
listener_->OnNewSegment("", kStartTime2, kDuration2, kSegmentFileSize2);
|
listener_->OnNewSegment("", kStartTime2, kDuration2, kSegmentFileSize2);
|
||||||
::testing::Mock::VerifyAndClearExpectations(notifier_.get());
|
::testing::Mock::VerifyAndClearExpectations(notifier_.get());
|
||||||
|
|
||||||
EXPECT_CALL(*notifier_, Flush()).Times(0);
|
EXPECT_CALL(*notifier_, Flush())
|
||||||
|
.Times(GetParam() == MpdType::kDynamic ? 0 : 1);
|
||||||
FireOnMediaEndWithParams(GetDefaultOnMediaEndParams());
|
FireOnMediaEndWithParams(GetDefaultOnMediaEndParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Live with key rotation. Note that OnEncryptionInfoReady() is called before
|
// Live with key rotation. Note that OnEncryptionInfoReady() is called before
|
||||||
// and after OnMediaStart().
|
// and after OnMediaStart().
|
||||||
TEST_F(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) {
|
TEST_P(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) {
|
||||||
SetupForLive();
|
SetupForLive();
|
||||||
MuxerOptions muxer_options;
|
MuxerOptions muxer_options;
|
||||||
SetDefaultLiveMuxerOptionsValues(&muxer_options);
|
SetDefaultLiveMuxerOptionsValues(&muxer_options);
|
||||||
|
@ -382,9 +394,12 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) {
|
||||||
EXPECT_CALL(*notifier_, NotifyEncryptionUpdate(_, _, _, _)).Times(1);
|
EXPECT_CALL(*notifier_, NotifyEncryptionUpdate(_, _, _, _)).Times(1);
|
||||||
EXPECT_CALL(*notifier_,
|
EXPECT_CALL(*notifier_,
|
||||||
NotifyNewSegment(_, kStartTime1, kDuration1, kSegmentFileSize1));
|
NotifyNewSegment(_, kStartTime1, kDuration1, kSegmentFileSize1));
|
||||||
|
// Flush should only be called once in OnMediaEnd.
|
||||||
|
if (GetParam() == MpdType::kDynamic)
|
||||||
EXPECT_CALL(*notifier_, Flush());
|
EXPECT_CALL(*notifier_, Flush());
|
||||||
EXPECT_CALL(*notifier_,
|
EXPECT_CALL(*notifier_,
|
||||||
NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2));
|
NotifyNewSegment(_, kStartTime2, kDuration2, kSegmentFileSize2));
|
||||||
|
if (GetParam() == MpdType::kDynamic)
|
||||||
EXPECT_CALL(*notifier_, Flush());
|
EXPECT_CALL(*notifier_, Flush());
|
||||||
|
|
||||||
std::vector<uint8_t> iv(kBogusIv, kBogusIv + arraysize(kBogusIv));
|
std::vector<uint8_t> iv(kBogusIv, kBogusIv + arraysize(kBogusIv));
|
||||||
|
@ -401,9 +416,14 @@ TEST_F(MpdNotifyMuxerListenerTest, LiveWithKeyRotation) {
|
||||||
listener_->OnNewSegment("", kStartTime2, kDuration2, kSegmentFileSize2);
|
listener_->OnNewSegment("", kStartTime2, kDuration2, kSegmentFileSize2);
|
||||||
::testing::Mock::VerifyAndClearExpectations(notifier_.get());
|
::testing::Mock::VerifyAndClearExpectations(notifier_.get());
|
||||||
|
|
||||||
EXPECT_CALL(*notifier_, Flush()).Times(0);
|
EXPECT_CALL(*notifier_, Flush())
|
||||||
|
.Times(GetParam() == MpdType::kDynamic ? 0 : 1);
|
||||||
FireOnMediaEndWithParams(GetDefaultOnMediaEndParams());
|
FireOnMediaEndWithParams(GetDefaultOnMediaEndParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(StaticAndDynamic,
|
||||||
|
MpdNotifyMuxerListenerTest,
|
||||||
|
::testing::Values(MpdType::kStatic, MpdType::kDynamic));
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
|
@ -39,17 +39,12 @@ std::set<std::string> GetUUIDs(
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
DashIopMpdNotifier::DashIopMpdNotifier(
|
DashIopMpdNotifier::DashIopMpdNotifier(
|
||||||
DashProfile dash_profile,
|
|
||||||
const MpdOptions& mpd_options,
|
const MpdOptions& mpd_options,
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path)
|
const std::string& output_path)
|
||||||
: MpdNotifier(dash_profile),
|
: MpdNotifier(mpd_options),
|
||||||
output_path_(output_path),
|
output_path_(output_path),
|
||||||
mpd_builder_(new MpdBuilder(dash_profile == kLiveProfile
|
mpd_builder_(new MpdBuilder(mpd_options)) {
|
||||||
? MpdBuilder::kDynamic
|
|
||||||
: MpdBuilder::kStatic,
|
|
||||||
mpd_options)) {
|
|
||||||
DCHECK(dash_profile == kLiveProfile || dash_profile == kOnDemandProfile);
|
|
||||||
for (size_t i = 0; i < base_urls.size(); ++i)
|
for (size_t i = 0; i < base_urls.size(); ++i)
|
||||||
mpd_builder_->AddBaseUrl(base_urls[i]);
|
mpd_builder_->AddBaseUrl(base_urls[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,7 @@ namespace shaka {
|
||||||
/// All video Adaptation Sets have Role set to "main".
|
/// All video Adaptation Sets have Role set to "main".
|
||||||
class DashIopMpdNotifier : public MpdNotifier {
|
class DashIopMpdNotifier : public MpdNotifier {
|
||||||
public:
|
public:
|
||||||
DashIopMpdNotifier(DashProfile dash_profile,
|
DashIopMpdNotifier(const MpdOptions& mpd_options,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path);
|
const std::string& output_path);
|
||||||
~DashIopMpdNotifier() override;
|
~DashIopMpdNotifier() override;
|
||||||
|
|
|
@ -91,8 +91,7 @@ MATCHER_P(ContentProtectionElementEq, expected, "") {
|
||||||
// (https://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests);
|
// (https://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests);
|
||||||
// also because SimpleMpdNotifier and DashIopMpdNotifier have common behavior
|
// also because SimpleMpdNotifier and DashIopMpdNotifier have common behavior
|
||||||
// for most of the public functions.
|
// for most of the public functions.
|
||||||
class DashIopMpdNotifierTest
|
class DashIopMpdNotifierTest : public ::testing::Test {
|
||||||
: public ::testing::TestWithParam<MpdBuilder::MpdType> {
|
|
||||||
protected:
|
protected:
|
||||||
DashIopMpdNotifierTest()
|
DashIopMpdNotifierTest()
|
||||||
: default_mock_adaptation_set_(
|
: default_mock_adaptation_set_(
|
||||||
|
@ -109,23 +108,11 @@ class DashIopMpdNotifierTest
|
||||||
base::DeleteFile(temp_file_path_, false /* non recursive, just 1 file */);
|
base::DeleteFile(temp_file_path_, false /* non recursive, just 1 file */);
|
||||||
}
|
}
|
||||||
|
|
||||||
MpdBuilder::MpdType GetMpdBuilderType(const DashIopMpdNotifier& notifier) {
|
|
||||||
return notifier.MpdBuilderForTesting()->type();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMpdBuilder(DashIopMpdNotifier* notifier,
|
void SetMpdBuilder(DashIopMpdNotifier* notifier,
|
||||||
std::unique_ptr<MpdBuilder> mpd_builder) {
|
std::unique_ptr<MpdBuilder> mpd_builder) {
|
||||||
notifier->SetMpdBuilderForTesting(std::move(mpd_builder));
|
notifier->SetMpdBuilderForTesting(std::move(mpd_builder));
|
||||||
}
|
}
|
||||||
|
|
||||||
MpdBuilder::MpdType mpd_type() {
|
|
||||||
return GetParam();
|
|
||||||
}
|
|
||||||
|
|
||||||
DashProfile dash_profile() {
|
|
||||||
return mpd_type() == MpdBuilder::kStatic ? kOnDemandProfile : kLiveProfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use output_path_ for specifying the MPD output path so that
|
// Use output_path_ for specifying the MPD output path so that
|
||||||
// WriteMpdToFile() doesn't crash.
|
// WriteMpdToFile() doesn't crash.
|
||||||
std::string output_path_;
|
std::string output_path_;
|
||||||
|
@ -142,27 +129,13 @@ class DashIopMpdNotifierTest
|
||||||
base::FilePath temp_file_path_;
|
base::FilePath temp_file_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Verify that it creates the correct MpdBuilder type using DashProfile passed
|
|
||||||
// to the constructor.
|
|
||||||
TEST_F(DashIopMpdNotifierTest, CreateCorrectMpdBuilderType) {
|
|
||||||
DashIopMpdNotifier on_demand_notifier(kOnDemandProfile, empty_mpd_option_,
|
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
EXPECT_TRUE(on_demand_notifier.Init());
|
|
||||||
EXPECT_EQ(MpdBuilder::kStatic, GetMpdBuilderType(on_demand_notifier));
|
|
||||||
DashIopMpdNotifier live_notifier(kLiveProfile, empty_mpd_option_,
|
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
EXPECT_TRUE(live_notifier.Init());
|
|
||||||
EXPECT_EQ(MpdBuilder::kDynamic, GetMpdBuilderType(live_notifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that basic VOD NotifyNewContainer() operation works.
|
// Verify that basic VOD NotifyNewContainer() operation works.
|
||||||
// No encrypted contents.
|
// No encrypted contents.
|
||||||
TEST_P(DashIopMpdNotifierTest, NotifyNewContainer) {
|
TEST_F(DashIopMpdNotifierTest, NotifyNewContainer) {
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
|
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
@ -183,18 +156,17 @@ TEST_P(DashIopMpdNotifierTest, NotifyNewContainer) {
|
||||||
|
|
||||||
// Verify that if the MediaInfo contains text information, then
|
// Verify that if the MediaInfo contains text information, then
|
||||||
// MpdBuilder::ForceSetSegmentAlignment() is called.
|
// MpdBuilder::ForceSetSegmentAlignment() is called.
|
||||||
TEST_P(DashIopMpdNotifierTest, NotifyNewTextContainer) {
|
TEST_F(DashIopMpdNotifierTest, NotifyNewTextContainer) {
|
||||||
const char kTextMediaInfo[] =
|
const char kTextMediaInfo[] =
|
||||||
"text_info {\n"
|
"text_info {\n"
|
||||||
" format: 'ttml'\n"
|
" format: 'ttml'\n"
|
||||||
" language: 'en'\n"
|
" language: 'en'\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: CONTAINER_TEXT\n";
|
"container_type: CONTAINER_TEXT\n";
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
|
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(StrEq("en")))
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(StrEq("en")))
|
||||||
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
@ -218,12 +190,11 @@ TEST_P(DashIopMpdNotifierTest, NotifyNewTextContainer) {
|
||||||
// MediaInfo::ProtectedContent.
|
// MediaInfo::ProtectedContent.
|
||||||
// Two AdaptationSets should be created.
|
// Two AdaptationSets should be created.
|
||||||
// AdaptationSets with different DRM won't be switchable.
|
// AdaptationSets with different DRM won't be switchable.
|
||||||
TEST_P(DashIopMpdNotifierTest,
|
TEST_F(DashIopMpdNotifierTest,
|
||||||
NotifyNewContainersWithDifferentProtectedContent) {
|
NotifyNewContainersWithDifferentProtectedContent) {
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
// Note they both have different (bogus) pssh, like real use case.
|
// Note they both have different (bogus) pssh, like real use case.
|
||||||
// default Key ID = _default_key_id_
|
// default Key ID = _default_key_id_
|
||||||
|
@ -338,11 +309,10 @@ TEST_P(DashIopMpdNotifierTest,
|
||||||
// Verify VOD NotifyNewContainer() operation works with same
|
// Verify VOD NotifyNewContainer() operation works with same
|
||||||
// MediaInfo::ProtectedContent. Only one AdaptationSet should be
|
// MediaInfo::ProtectedContent. Only one AdaptationSet should be
|
||||||
// created.
|
// created.
|
||||||
TEST_P(DashIopMpdNotifierTest, NotifyNewContainersWithSameProtectedContent) {
|
TEST_F(DashIopMpdNotifierTest, NotifyNewContainersWithSameProtectedContent) {
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
// These have the same default key ID and PSSH.
|
// These have the same default key ID and PSSH.
|
||||||
const char kSdProtectedContent[] =
|
const char kSdProtectedContent[] =
|
||||||
|
@ -441,12 +411,11 @@ TEST_P(DashIopMpdNotifierTest, NotifyNewContainersWithSameProtectedContent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddContentProtection() should not work and should always return false.
|
// AddContentProtection() should not work and should always return false.
|
||||||
TEST_P(DashIopMpdNotifierTest, AddContentProtection) {
|
TEST_F(DashIopMpdNotifierTest, AddContentProtection) {
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
|
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
@ -473,11 +442,10 @@ TEST_P(DashIopMpdNotifierTest, AddContentProtection) {
|
||||||
// should be switchable.
|
// should be switchable.
|
||||||
// 3. Add a 4k protected content. This should also make a new AdaptationSet.
|
// 3. Add a 4k protected content. This should also make a new AdaptationSet.
|
||||||
// It should be switchable with SD/HD AdaptationSet.
|
// It should be switchable with SD/HD AdaptationSet.
|
||||||
TEST_P(DashIopMpdNotifierTest, SetAdaptationSetSwitching) {
|
TEST_F(DashIopMpdNotifierTest, SetAdaptationSetSwitching) {
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
// These have the same default key ID and PSSH.
|
// These have the same default key ID and PSSH.
|
||||||
const char kSdProtectedContent[] =
|
const char kSdProtectedContent[] =
|
||||||
|
@ -610,12 +578,11 @@ TEST_P(DashIopMpdNotifierTest, SetAdaptationSetSwitching) {
|
||||||
|
|
||||||
// Even if the UUIDs match, video and audio AdaptationSets should not be
|
// Even if the UUIDs match, video and audio AdaptationSets should not be
|
||||||
// switchable.
|
// switchable.
|
||||||
TEST_P(DashIopMpdNotifierTest,
|
TEST_F(DashIopMpdNotifierTest,
|
||||||
DoNotSetAdaptationSetSwitchingIfContentTypesDifferent) {
|
DoNotSetAdaptationSetSwitchingIfContentTypesDifferent) {
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
// These have the same default key ID and PSSH.
|
// These have the same default key ID and PSSH.
|
||||||
const char kVideoContent[] =
|
const char kVideoContent[] =
|
||||||
|
@ -699,7 +666,7 @@ TEST_P(DashIopMpdNotifierTest,
|
||||||
ElementsAre());
|
ElementsAre());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DashIopMpdNotifierTest, UpdateEncryption) {
|
TEST_F(DashIopMpdNotifierTest, UpdateEncryption) {
|
||||||
const char kProtectedContent[] =
|
const char kProtectedContent[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
" codec: 'avc1'\n"
|
" codec: 'avc1'\n"
|
||||||
|
@ -720,11 +687,10 @@ TEST_P(DashIopMpdNotifierTest, UpdateEncryption) {
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
|
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
|
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
||||||
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
||||||
|
@ -761,8 +727,8 @@ TEST_P(DashIopMpdNotifierTest, UpdateEncryption) {
|
||||||
// This issue identified a bug where using SimpleMpdNotifier with multiple
|
// This issue identified a bug where using SimpleMpdNotifier with multiple
|
||||||
// threads causes a deadlock. This tests with DashIopMpdNotifier.
|
// threads causes a deadlock. This tests with DashIopMpdNotifier.
|
||||||
TEST_F(DashIopMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
|
TEST_F(DashIopMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
|
||||||
DashIopMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
uint32_t container_id;
|
uint32_t container_id;
|
||||||
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
&container_id));
|
&container_id));
|
||||||
|
@ -772,7 +738,7 @@ TEST_F(DashIopMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't put different audio languages or codecs in the same AdaptationSet.
|
// Don't put different audio languages or codecs in the same AdaptationSet.
|
||||||
TEST_P(DashIopMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
TEST_F(DashIopMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
||||||
// MP4, English
|
// MP4, English
|
||||||
const char kAudioContent1[] =
|
const char kAudioContent1[] =
|
||||||
"audio_info {\n"
|
"audio_info {\n"
|
||||||
|
@ -825,10 +791,9 @@ TEST_P(DashIopMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
||||||
"container_type: CONTAINER_WEBM\n"
|
"container_type: CONTAINER_WEBM\n"
|
||||||
"media_duration_seconds: 10.5\n";
|
"media_duration_seconds: 10.5\n";
|
||||||
|
|
||||||
DashIopMpdNotifier notifier(dash_profile(), empty_mpd_option_,
|
DashIopMpdNotifier notifier(empty_mpd_option_, empty_base_urls_,
|
||||||
empty_base_urls_, output_path_);
|
output_path_);
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
new MockMpdBuilder(mpd_type()));
|
|
||||||
|
|
||||||
std::unique_ptr<MockAdaptationSet> adaptation_set1(new MockAdaptationSet(1));
|
std::unique_ptr<MockAdaptationSet> adaptation_set1(new MockAdaptationSet(1));
|
||||||
std::unique_ptr<MockAdaptationSet> adaptation_set2(new MockAdaptationSet(2));
|
std::unique_ptr<MockAdaptationSet> adaptation_set2(new MockAdaptationSet(2));
|
||||||
|
@ -871,10 +836,4 @@ TEST_P(DashIopMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
||||||
ConvertToMediaInfo(kAudioContent4), &unused_container_id));
|
ConvertToMediaInfo(kAudioContent4), &unused_container_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(StaticAndDynamic,
|
|
||||||
DashIopMpdNotifierTest,
|
|
||||||
::testing::Values(MpdBuilder::kStatic,
|
|
||||||
MpdBuilder::kDynamic));
|
|
||||||
|
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
|
@ -6,20 +6,17 @@ namespace shaka {
|
||||||
namespace {
|
namespace {
|
||||||
const char kEmptyLang[] = "";
|
const char kEmptyLang[] = "";
|
||||||
const MpdOptions kDefaultMpdOptions;
|
const MpdOptions kDefaultMpdOptions;
|
||||||
const MpdBuilder::MpdType kDefaultMpdType = MpdBuilder::kStatic;
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Doesn't matter what values get passed to the super class' constructor.
|
// Doesn't matter what values get passed to the super class' constructor.
|
||||||
// All methods used for testing should be mocked.
|
// All methods used for testing should be mocked.
|
||||||
MockMpdBuilder::MockMpdBuilder(MpdType type)
|
MockMpdBuilder::MockMpdBuilder() : MpdBuilder(kDefaultMpdOptions) {}
|
||||||
: MpdBuilder(type, kDefaultMpdOptions) {}
|
|
||||||
MockMpdBuilder::~MockMpdBuilder() {}
|
MockMpdBuilder::~MockMpdBuilder() {}
|
||||||
|
|
||||||
MockAdaptationSet::MockAdaptationSet(uint32_t adaptation_set_id)
|
MockAdaptationSet::MockAdaptationSet(uint32_t adaptation_set_id)
|
||||||
: AdaptationSet(adaptation_set_id,
|
: AdaptationSet(adaptation_set_id,
|
||||||
kEmptyLang,
|
kEmptyLang,
|
||||||
kDefaultMpdOptions,
|
kDefaultMpdOptions,
|
||||||
kDefaultMpdType,
|
|
||||||
&sequence_counter_) {}
|
&sequence_counter_) {}
|
||||||
MockAdaptationSet::~MockAdaptationSet() {}
|
MockAdaptationSet::~MockAdaptationSet() {}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,7 @@ namespace shaka {
|
||||||
|
|
||||||
class MockMpdBuilder : public MpdBuilder {
|
class MockMpdBuilder : public MpdBuilder {
|
||||||
public:
|
public:
|
||||||
// |type| indicates whether the MPD should be for VOD or live content (kStatic
|
MockMpdBuilder();
|
||||||
// for VOD profile, or kDynamic for live profile).
|
|
||||||
explicit MockMpdBuilder(MpdType type);
|
|
||||||
~MockMpdBuilder() override;
|
~MockMpdBuilder() override;
|
||||||
|
|
||||||
MOCK_METHOD1(AddAdaptationSet, AdaptationSet*(const std::string& lang));
|
MOCK_METHOD1(AddAdaptationSet, AdaptationSet*(const std::string& lang));
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
|
||||||
MockMpdNotifier::MockMpdNotifier(DashProfile profile) : MpdNotifier(profile) {}
|
MockMpdNotifier::MockMpdNotifier(const MpdOptions& mpd_options)
|
||||||
|
: MpdNotifier(mpd_options) {}
|
||||||
MockMpdNotifier::~MockMpdNotifier() {}
|
MockMpdNotifier::~MockMpdNotifier() {}
|
||||||
|
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace shaka {
|
||||||
|
|
||||||
class MockMpdNotifier : public MpdNotifier {
|
class MockMpdNotifier : public MpdNotifier {
|
||||||
public:
|
public:
|
||||||
MockMpdNotifier(DashProfile profile);
|
explicit MockMpdNotifier(const MpdOptions& mpd_options);
|
||||||
virtual ~MockMpdNotifier();
|
virtual ~MockMpdNotifier();
|
||||||
|
|
||||||
MOCK_METHOD0(Init, bool());
|
MOCK_METHOD0(Init, bool());
|
||||||
|
|
|
@ -396,10 +396,8 @@ class RepresentationStateChangeListenerImpl
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MpdBuilder::MpdBuilder(MpdType type, const MpdOptions& mpd_options)
|
MpdBuilder::MpdBuilder(const MpdOptions& mpd_options)
|
||||||
: type_(type),
|
: mpd_options_(mpd_options), clock_(new base::DefaultClock()) {}
|
||||||
mpd_options_(mpd_options),
|
|
||||||
clock_(new base::DefaultClock()) {}
|
|
||||||
|
|
||||||
MpdBuilder::~MpdBuilder() {}
|
MpdBuilder::~MpdBuilder() {}
|
||||||
|
|
||||||
|
@ -410,7 +408,7 @@ void MpdBuilder::AddBaseUrl(const std::string& base_url) {
|
||||||
AdaptationSet* MpdBuilder::AddAdaptationSet(const std::string& lang) {
|
AdaptationSet* MpdBuilder::AddAdaptationSet(const std::string& lang) {
|
||||||
std::unique_ptr<AdaptationSet> adaptation_set(
|
std::unique_ptr<AdaptationSet> adaptation_set(
|
||||||
new AdaptationSet(adaptation_set_counter_.GetNext(), lang, mpd_options_,
|
new AdaptationSet(adaptation_set_counter_.GetNext(), lang, mpd_options_,
|
||||||
type_, &representation_counter_));
|
&representation_counter_));
|
||||||
DCHECK(adaptation_set);
|
DCHECK(adaptation_set);
|
||||||
|
|
||||||
if (!lang.empty() && lang == mpd_options_.default_language) {
|
if (!lang.empty() && lang == mpd_options_.default_language) {
|
||||||
|
@ -482,7 +480,8 @@ xmlDocPtr MpdBuilder::GenerateMpd() {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_ == kDynamic) {
|
// TODO(kqyang): Should we set @start unconditionally to 0?
|
||||||
|
if (mpd_options_.mpd_type == MpdType::kDynamic) {
|
||||||
// This is the only Period and it is a regular period.
|
// This is the only Period and it is a regular period.
|
||||||
period.SetStringAttribute("start", "PT0S");
|
period.SetStringAttribute("start", "PT0S");
|
||||||
}
|
}
|
||||||
|
@ -491,16 +490,35 @@ xmlDocPtr MpdBuilder::GenerateMpd() {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
AddMpdNameSpaceInfo(&mpd);
|
AddMpdNameSpaceInfo(&mpd);
|
||||||
|
|
||||||
|
static const char kOnDemandProfile[] =
|
||||||
|
"urn:mpeg:dash:profile:isoff-on-demand:2011";
|
||||||
|
static const char kLiveProfile[] =
|
||||||
|
"urn:mpeg:dash:profile:isoff-live:2011";
|
||||||
|
switch (mpd_options_.dash_profile) {
|
||||||
|
case DashProfile::kOnDemand:
|
||||||
|
mpd.SetStringAttribute("profiles", kOnDemandProfile);
|
||||||
|
break;
|
||||||
|
case DashProfile::kLive:
|
||||||
|
mpd.SetStringAttribute("profiles", kLiveProfile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NOTREACHED() << "Unknown DASH profile: "
|
||||||
|
<< static_cast<int>(mpd_options_.dash_profile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
AddCommonMpdInfo(&mpd);
|
AddCommonMpdInfo(&mpd);
|
||||||
switch (type_) {
|
switch (mpd_options_.mpd_type) {
|
||||||
case kStatic:
|
case MpdType::kStatic:
|
||||||
AddStaticMpdInfo(&mpd);
|
AddStaticMpdInfo(&mpd);
|
||||||
break;
|
break;
|
||||||
case kDynamic:
|
case MpdType::kDynamic:
|
||||||
AddDynamicMpdInfo(&mpd);
|
AddDynamicMpdInfo(&mpd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NOTREACHED() << "Unknown MPD type: " << type_;
|
NOTREACHED() << "Unknown MPD type: "
|
||||||
|
<< static_cast<int>(mpd_options_.mpd_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,13 +550,10 @@ void MpdBuilder::AddCommonMpdInfo(XmlNode* mpd_node) {
|
||||||
|
|
||||||
void MpdBuilder::AddStaticMpdInfo(XmlNode* mpd_node) {
|
void MpdBuilder::AddStaticMpdInfo(XmlNode* mpd_node) {
|
||||||
DCHECK(mpd_node);
|
DCHECK(mpd_node);
|
||||||
DCHECK_EQ(MpdBuilder::kStatic, type_);
|
DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
|
||||||
|
|
||||||
static const char kStaticMpdType[] = "static";
|
static const char kStaticMpdType[] = "static";
|
||||||
static const char kStaticMpdProfile[] =
|
|
||||||
"urn:mpeg:dash:profile:isoff-on-demand:2011";
|
|
||||||
mpd_node->SetStringAttribute("type", kStaticMpdType);
|
mpd_node->SetStringAttribute("type", kStaticMpdType);
|
||||||
mpd_node->SetStringAttribute("profiles", kStaticMpdProfile);
|
|
||||||
mpd_node->SetStringAttribute(
|
mpd_node->SetStringAttribute(
|
||||||
"mediaPresentationDuration",
|
"mediaPresentationDuration",
|
||||||
SecondsToXmlDuration(GetStaticMpdDuration(mpd_node)));
|
SecondsToXmlDuration(GetStaticMpdDuration(mpd_node)));
|
||||||
|
@ -546,13 +561,10 @@ void MpdBuilder::AddStaticMpdInfo(XmlNode* mpd_node) {
|
||||||
|
|
||||||
void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
|
void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
|
||||||
DCHECK(mpd_node);
|
DCHECK(mpd_node);
|
||||||
DCHECK_EQ(MpdBuilder::kDynamic, type_);
|
DCHECK_EQ(MpdType::kDynamic, mpd_options_.mpd_type);
|
||||||
|
|
||||||
static const char kDynamicMpdType[] = "dynamic";
|
static const char kDynamicMpdType[] = "dynamic";
|
||||||
static const char kDynamicMpdProfile[] =
|
|
||||||
"urn:mpeg:dash:profile:isoff-live:2011";
|
|
||||||
mpd_node->SetStringAttribute("type", kDynamicMpdType);
|
mpd_node->SetStringAttribute("type", kDynamicMpdType);
|
||||||
mpd_node->SetStringAttribute("profiles", kDynamicMpdProfile);
|
|
||||||
|
|
||||||
// No offset from NOW.
|
// No offset from NOW.
|
||||||
mpd_node->SetStringAttribute("publishTime",
|
mpd_node->SetStringAttribute("publishTime",
|
||||||
|
@ -594,12 +606,13 @@ void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
|
||||||
|
|
||||||
float MpdBuilder::GetStaticMpdDuration(XmlNode* mpd_node) {
|
float MpdBuilder::GetStaticMpdDuration(XmlNode* mpd_node) {
|
||||||
DCHECK(mpd_node);
|
DCHECK(mpd_node);
|
||||||
DCHECK_EQ(MpdBuilder::kStatic, type_);
|
DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
|
||||||
|
|
||||||
xmlNodePtr period_node = FindPeriodNode(mpd_node);
|
xmlNodePtr period_node = FindPeriodNode(mpd_node);
|
||||||
DCHECK(period_node) << "Period element must be a child of mpd_node.";
|
DCHECK(period_node) << "Period element must be a child of mpd_node.";
|
||||||
DCHECK(IsPeriodNode(period_node));
|
DCHECK(IsPeriodNode(period_node));
|
||||||
|
|
||||||
|
// TODO(kqyang): Verify if this works for static + live profile.
|
||||||
// Attribute mediaPresentationDuration must be present for 'static' MPD. So
|
// Attribute mediaPresentationDuration must be present for 'static' MPD. So
|
||||||
// setting "PT0S" is required even if none of the representaions have duration
|
// setting "PT0S" is required even if none of the representaions have duration
|
||||||
// attribute.
|
// attribute.
|
||||||
|
@ -673,13 +686,11 @@ void MpdBuilder::MakePathsRelativeToMpd(const std::string& mpd_path,
|
||||||
AdaptationSet::AdaptationSet(uint32_t adaptation_set_id,
|
AdaptationSet::AdaptationSet(uint32_t adaptation_set_id,
|
||||||
const std::string& lang,
|
const std::string& lang,
|
||||||
const MpdOptions& mpd_options,
|
const MpdOptions& mpd_options,
|
||||||
MpdBuilder::MpdType mpd_type,
|
|
||||||
base::AtomicSequenceNumber* counter)
|
base::AtomicSequenceNumber* counter)
|
||||||
: representation_counter_(counter),
|
: representation_counter_(counter),
|
||||||
id_(adaptation_set_id),
|
id_(adaptation_set_id),
|
||||||
lang_(lang),
|
lang_(lang),
|
||||||
mpd_options_(mpd_options),
|
mpd_options_(mpd_options),
|
||||||
mpd_type_(mpd_type),
|
|
||||||
segments_aligned_(kSegmentAlignmentUnknown),
|
segments_aligned_(kSegmentAlignmentUnknown),
|
||||||
force_set_segment_alignment_(false) {
|
force_set_segment_alignment_(false) {
|
||||||
DCHECK(counter);
|
DCHECK(counter);
|
||||||
|
@ -791,12 +802,13 @@ xml::scoped_xml_ptr<xmlNode> AdaptationSet::GetXml() {
|
||||||
|
|
||||||
// Note: must be checked before checking segments_aligned_ (below). So that
|
// Note: must be checked before checking segments_aligned_ (below). So that
|
||||||
// segments_aligned_ is set before checking below.
|
// segments_aligned_ is set before checking below.
|
||||||
if (mpd_type_ == MpdBuilder::kStatic) {
|
if (mpd_options_.dash_profile == DashProfile::kOnDemand) {
|
||||||
CheckVodSegmentAlignment();
|
CheckVodSegmentAlignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segments_aligned_ == kSegmentAlignmentTrue) {
|
if (segments_aligned_ == kSegmentAlignmentTrue) {
|
||||||
adaptation_set.SetStringAttribute(mpd_type_ == MpdBuilder::kStatic
|
adaptation_set.SetStringAttribute(
|
||||||
|
mpd_options_.dash_profile == DashProfile::kOnDemand
|
||||||
? "subsegmentAlignment"
|
? "subsegmentAlignment"
|
||||||
: "segmentAlignment",
|
: "segmentAlignment",
|
||||||
"true");
|
"true");
|
||||||
|
@ -860,7 +872,7 @@ void AdaptationSet::AddAdaptationSetSwitching(uint32_t adaptation_set_id) {
|
||||||
void AdaptationSet::OnNewSegmentForRepresentation(uint32_t representation_id,
|
void AdaptationSet::OnNewSegmentForRepresentation(uint32_t representation_id,
|
||||||
uint64_t start_time,
|
uint64_t start_time,
|
||||||
uint64_t duration) {
|
uint64_t duration) {
|
||||||
if (mpd_type_ == MpdBuilder::kDynamic) {
|
if (mpd_options_.dash_profile == DashProfile::kLive) {
|
||||||
CheckLiveSegmentAlignment(representation_id, start_time, duration);
|
CheckLiveSegmentAlignment(representation_id, start_time, duration);
|
||||||
} else {
|
} else {
|
||||||
representation_segment_start_times_[representation_id].push_back(
|
representation_segment_start_times_[representation_id].push_back(
|
||||||
|
|
|
@ -56,15 +56,9 @@ class RepresentationXmlNode;
|
||||||
/// This class generates DASH MPDs (Media Presentation Descriptions).
|
/// This class generates DASH MPDs (Media Presentation Descriptions).
|
||||||
class MpdBuilder {
|
class MpdBuilder {
|
||||||
public:
|
public:
|
||||||
enum MpdType {
|
|
||||||
kStatic = 0,
|
|
||||||
kDynamic
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Constructs MpdBuilder.
|
/// Constructs MpdBuilder.
|
||||||
/// @param type indicates whether the MPD should be for VOD or live content
|
/// @param mpd_options contains options on how this MPD should be built.
|
||||||
/// (kStatic for VOD profile, or kDynamic for live profile).
|
explicit MpdBuilder(const MpdOptions& mpd_options);
|
||||||
MpdBuilder(MpdType type, const MpdOptions& mpd_options);
|
|
||||||
virtual ~MpdBuilder();
|
virtual ~MpdBuilder();
|
||||||
|
|
||||||
/// Add <BaseURL> entry to the MPD.
|
/// Add <BaseURL> entry to the MPD.
|
||||||
|
@ -88,9 +82,6 @@ class MpdBuilder {
|
||||||
/// @return true on success, false otherwise.
|
/// @return true on success, false otherwise.
|
||||||
virtual bool ToString(std::string* output);
|
virtual bool ToString(std::string* output);
|
||||||
|
|
||||||
/// @return The mpd type.
|
|
||||||
MpdType type() const { return type_; }
|
|
||||||
|
|
||||||
/// Adjusts the fields of MediaInfo so that paths are relative to the
|
/// Adjusts the fields of MediaInfo so that paths are relative to the
|
||||||
/// specified MPD path.
|
/// specified MPD path.
|
||||||
/// @param mpd_path is the file path of the MPD file.
|
/// @param mpd_path is the file path of the MPD file.
|
||||||
|
@ -106,9 +97,11 @@ class MpdBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// DynamicMpdBuilderTest needs to set availabilityStartTime so that the test
|
// LiveMpdBuilderTest needs to set availabilityStartTime so that the test
|
||||||
// doesn't need to depend on current time.
|
// doesn't need to depend on current time.
|
||||||
friend class DynamicMpdBuilderTest;
|
friend class LiveMpdBuilderTest;
|
||||||
|
template <DashProfile profile>
|
||||||
|
friend class MpdBuilderTest;
|
||||||
|
|
||||||
bool ToStringImpl(std::string* output);
|
bool ToStringImpl(std::string* output);
|
||||||
|
|
||||||
|
@ -143,7 +136,6 @@ class MpdBuilder {
|
||||||
// successful, false otherwise.
|
// successful, false otherwise.
|
||||||
bool GetEarliestTimestamp(double* timestamp_seconds);
|
bool GetEarliestTimestamp(double* timestamp_seconds);
|
||||||
|
|
||||||
MpdType type_;
|
|
||||||
MpdOptions mpd_options_;
|
MpdOptions mpd_options_;
|
||||||
std::list<std::unique_ptr<AdaptationSet>> adaptation_sets_;
|
std::list<std::unique_ptr<AdaptationSet>> adaptation_sets_;
|
||||||
|
|
||||||
|
@ -286,12 +278,11 @@ class AdaptationSet {
|
||||||
AdaptationSet(uint32_t adaptation_set_id,
|
AdaptationSet(uint32_t adaptation_set_id,
|
||||||
const std::string& lang,
|
const std::string& lang,
|
||||||
const MpdOptions& mpd_options,
|
const MpdOptions& mpd_options,
|
||||||
MpdBuilder::MpdType mpd_type,
|
|
||||||
base::AtomicSequenceNumber* representation_counter);
|
base::AtomicSequenceNumber* representation_counter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MpdBuilder;
|
friend class MpdBuilder;
|
||||||
template <MpdBuilder::MpdType type>
|
template <DashProfile profile>
|
||||||
friend class MpdBuilderTest;
|
friend class MpdBuilderTest;
|
||||||
|
|
||||||
// kSegmentAlignmentUnknown means that it is uncertain if the
|
// kSegmentAlignmentUnknown means that it is uncertain if the
|
||||||
|
@ -345,7 +336,6 @@ class AdaptationSet {
|
||||||
const uint32_t id_;
|
const uint32_t id_;
|
||||||
const std::string lang_;
|
const std::string lang_;
|
||||||
const MpdOptions& mpd_options_;
|
const MpdOptions& mpd_options_;
|
||||||
const MpdBuilder::MpdType mpd_type_;
|
|
||||||
|
|
||||||
// The ids of the adaptation sets this adaptation set can switch to.
|
// The ids of the adaptation sets this adaptation set can switch to.
|
||||||
std::vector<uint32_t> adaptation_set_switching_ids_;
|
std::vector<uint32_t> adaptation_set_switching_ids_;
|
||||||
|
@ -513,7 +503,7 @@ class Representation {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class AdaptationSet;
|
friend class AdaptationSet;
|
||||||
template <MpdBuilder::MpdType type>
|
template <DashProfile profile>
|
||||||
friend class MpdBuilderTest;
|
friend class MpdBuilderTest;
|
||||||
|
|
||||||
bool AddLiveInfo(xml::RepresentationXmlNode* representation);
|
bool AddLiveInfo(xml::RepresentationXmlNode* representation);
|
||||||
|
|
|
@ -104,12 +104,16 @@ class MockRepresentationStateChangeListener
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template <MpdBuilder::MpdType type>
|
template <DashProfile profile>
|
||||||
class MpdBuilderTest : public ::testing::Test {
|
class MpdBuilderTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
MpdBuilderTest() : mpd_(type, MpdOptions()), representation_() {}
|
MpdBuilderTest() : mpd_(MpdOptions()), representation_() {
|
||||||
|
mpd_.mpd_options_.dash_profile = profile;
|
||||||
|
}
|
||||||
~MpdBuilderTest() override {}
|
~MpdBuilderTest() override {}
|
||||||
|
|
||||||
|
MpdOptions* mutable_mpd_options() { return &mpd_.mpd_options_; }
|
||||||
|
|
||||||
void CheckMpd(const std::string& expected_output_file) {
|
void CheckMpd(const std::string& expected_output_file) {
|
||||||
std::string mpd_doc;
|
std::string mpd_doc;
|
||||||
ASSERT_TRUE(mpd_.ToString(&mpd_doc));
|
ASSERT_TRUE(mpd_.ToString(&mpd_doc));
|
||||||
|
@ -138,24 +142,20 @@ class MpdBuilderTest : public ::testing::Test {
|
||||||
// constructor signatures.
|
// constructor signatures.
|
||||||
std::unique_ptr<Representation> CreateRepresentation(
|
std::unique_ptr<Representation> CreateRepresentation(
|
||||||
const MediaInfo& media_info,
|
const MediaInfo& media_info,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
uint32_t representation_id,
|
uint32_t representation_id,
|
||||||
std::unique_ptr<RepresentationStateChangeListener>
|
std::unique_ptr<RepresentationStateChangeListener>
|
||||||
state_change_listener) {
|
state_change_listener) {
|
||||||
return std::unique_ptr<Representation>(
|
return std::unique_ptr<Representation>(
|
||||||
new Representation(media_info, mpd_options, representation_id,
|
new Representation(media_info, mpd_options_, representation_id,
|
||||||
std::move(state_change_listener)));
|
std::move(state_change_listener)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AdaptationSet> CreateAdaptationSet(
|
std::unique_ptr<AdaptationSet> CreateAdaptationSet(
|
||||||
uint32_t adaptation_set_id,
|
uint32_t adaptation_set_id,
|
||||||
const std::string& lang,
|
const std::string& lang,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
MpdBuilder::MpdType mpd_type,
|
|
||||||
base::AtomicSequenceNumber* representation_counter) {
|
base::AtomicSequenceNumber* representation_counter) {
|
||||||
return std::unique_ptr<AdaptationSet>(
|
return std::unique_ptr<AdaptationSet>(new AdaptationSet(
|
||||||
new AdaptationSet(adaptation_set_id, lang, mpd_options, mpd_type,
|
adaptation_set_id, lang, mpd_options_, representation_counter));
|
||||||
representation_counter));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to return an empty listener for tests that don't need
|
// Helper function to return an empty listener for tests that don't need
|
||||||
|
@ -170,29 +170,30 @@ class MpdBuilderTest : public ::testing::Test {
|
||||||
Representation* representation_; // Owned by |mpd_|.
|
Representation* representation_; // Owned by |mpd_|.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MpdOptions mpd_options_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MpdBuilderTest);
|
DISALLOW_COPY_AND_ASSIGN(MpdBuilderTest);
|
||||||
};
|
};
|
||||||
|
|
||||||
class StaticMpdBuilderTest : public MpdBuilderTest<MpdBuilder::kStatic> {};
|
class OnDemandMpdBuilderTest : public MpdBuilderTest<DashProfile::kOnDemand> {};
|
||||||
|
|
||||||
// Use this test name for things that are common to both static an dynamic
|
// Use this test name for things that are common to both static an dynamic
|
||||||
// mpd builder tests.
|
// mpd builder tests.
|
||||||
typedef StaticMpdBuilderTest CommonMpdBuilderTest;
|
typedef OnDemandMpdBuilderTest CommonMpdBuilderTest;
|
||||||
|
|
||||||
class DynamicMpdBuilderTest : public MpdBuilderTest<MpdBuilder::kDynamic> {
|
class LiveMpdBuilderTest : public MpdBuilderTest<DashProfile::kLive> {
|
||||||
public:
|
public:
|
||||||
~DynamicMpdBuilderTest() override {}
|
~LiveMpdBuilderTest() override {}
|
||||||
|
|
||||||
// Anchors availabilityStartTime so that the test result doesn't depend on the
|
// Anchors availabilityStartTime so that the test result doesn't depend on the
|
||||||
// current time.
|
// current time.
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
SetPackagerVersionForTesting("<tag>-<hash>-<test>");
|
SetPackagerVersionForTesting("<tag>-<hash>-<test>");
|
||||||
|
mpd_.mpd_options_.mpd_type = MpdType::kDynamic;
|
||||||
mpd_.availability_start_time_ = "2011-12-25T12:30:00";
|
mpd_.availability_start_time_ = "2011-12-25T12:30:00";
|
||||||
InjectTestClock();
|
InjectTestClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
MpdOptions* mutable_mpd_options() { return &mpd_.mpd_options_; }
|
|
||||||
|
|
||||||
// Injects a clock that always returns 2016 Jan 11 15:10:24 in UTC.
|
// Injects a clock that always returns 2016 Jan 11 15:10:24 in UTC.
|
||||||
void InjectTestClock() {
|
void InjectTestClock() {
|
||||||
base::Time::Exploded test_time = { 2016, // year.
|
base::Time::Exploded test_time = { 2016, // year.
|
||||||
|
@ -231,14 +232,14 @@ class DynamicMpdBuilderTest : public MpdBuilderTest<MpdBuilder::kDynamic> {
|
||||||
uint32_t DefaultTimeScale() const { return 1000; };
|
uint32_t DefaultTimeScale() const { return 1000; };
|
||||||
};
|
};
|
||||||
|
|
||||||
class SegmentTemplateTest : public DynamicMpdBuilderTest {
|
class SegmentTemplateTest : public LiveMpdBuilderTest {
|
||||||
public:
|
public:
|
||||||
SegmentTemplateTest()
|
SegmentTemplateTest()
|
||||||
: bandwidth_estimator_(BandwidthEstimator::kUseAllBlocks) {}
|
: bandwidth_estimator_(BandwidthEstimator::kUseAllBlocks) {}
|
||||||
~SegmentTemplateTest() override {}
|
~SegmentTemplateTest() override {}
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
DynamicMpdBuilderTest::SetUp();
|
LiveMpdBuilderTest::SetUp();
|
||||||
ASSERT_NO_FATAL_FAILURE(AddRepresentationWithDefaultMediaInfo());
|
ASSERT_NO_FATAL_FAILURE(AddRepresentationWithDefaultMediaInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,8 +283,9 @@ class SegmentTemplateTest : public DynamicMpdBuilderTest {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
|
||||||
" availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
|
" availabilityStartTime=\"2011-12-25T12:30:00\" "
|
||||||
" type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
||||||
|
" minBufferTime=\"PT2S\" type=\"dynamic\" "
|
||||||
" publishTime=\"2016-01-11T15:10:24Z\">\n"
|
" publishTime=\"2016-01-11T15:10:24Z\">\n"
|
||||||
" <Period id=\"0\" start=\"PT0S\">\n"
|
" <Period id=\"0\" start=\"PT0S\">\n"
|
||||||
" <AdaptationSet id=\"0\" width=\"720\" height=\"480\""
|
" <AdaptationSet id=\"0\" width=\"720\" height=\"480\""
|
||||||
|
@ -331,7 +333,7 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
|
||||||
// that it does not automatically add a representation, that has $Time$
|
// that it does not automatically add a representation, that has $Time$
|
||||||
// template.
|
// template.
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
DynamicMpdBuilderTest::SetUp();
|
LiveMpdBuilderTest::SetUp();
|
||||||
|
|
||||||
// The only diff with current GetDefaultMediaInfo() is that this uses
|
// The only diff with current GetDefaultMediaInfo() is that this uses
|
||||||
// $Number$ for segment template.
|
// $Number$ for segment template.
|
||||||
|
@ -367,8 +369,9 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
|
||||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
||||||
"xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
|
"xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
|
||||||
"xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
|
"xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
|
||||||
"availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
|
"availabilityStartTime=\"2011-12-25T12:30:00\" "
|
||||||
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
"profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
||||||
|
"minBufferTime=\"PT2S\" type=\"dynamic\" "
|
||||||
"publishTime=\"2016-01-11T15:10:24Z\" "
|
"publishTime=\"2016-01-11T15:10:24Z\" "
|
||||||
"timeShiftBufferDepth=\"PT%dS\">\n"
|
"timeShiftBufferDepth=\"PT%dS\">\n"
|
||||||
" <Period id=\"0\" start=\"PT0S\">\n"
|
" <Period id=\"0\" start=\"PT0S\">\n"
|
||||||
|
@ -405,7 +408,7 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(CommonMpdBuilderTest, AddAdaptationSetSwitching) {
|
TEST_F(CommonMpdBuilderTest, AddAdaptationSetSwitching) {
|
||||||
MpdBuilder mpd_builder(MpdBuilder::kStatic, MpdOptions());
|
MpdBuilder mpd_builder(MpdOptions{});
|
||||||
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
|
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
|
||||||
adaptation_set->AddAdaptationSetSwitching(1);
|
adaptation_set->AddAdaptationSetSwitching(1);
|
||||||
adaptation_set->AddAdaptationSetSwitching(2);
|
adaptation_set->AddAdaptationSetSwitching(2);
|
||||||
|
@ -420,8 +423,8 @@ TEST_F(CommonMpdBuilderTest, AddAdaptationSetSwitching) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\"\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"
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\"\n"
|
||||||
" mediaPresentationDuration=\"PT0S\">\n"
|
" mediaPresentationDuration=\"PT0S\">\n"
|
||||||
" <Period id=\"0\">\n"
|
" <Period id=\"0\">\n"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"\">\n"
|
" <AdaptationSet id=\"0\" contentType=\"\">\n"
|
||||||
|
@ -454,9 +457,8 @@ TEST_F(CommonMpdBuilderTest, ValidMediaInfo) {
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
|
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kTestMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,9 +466,8 @@ TEST_F(CommonMpdBuilderTest, ValidMediaInfo) {
|
||||||
TEST_F(CommonMpdBuilderTest, VideoAudioTextInfoNotSet) {
|
TEST_F(CommonMpdBuilderTest, VideoAudioTextInfoNotSet) {
|
||||||
const char kTestMediaInfo[] = "container_type: 1";
|
const char kTestMediaInfo[] = "container_type: 1";
|
||||||
|
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kTestMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
EXPECT_FALSE(representation->Init());
|
EXPECT_FALSE(representation->Init());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,9 +491,8 @@ TEST_F(CommonMpdBuilderTest, VideoAndAudioInfoSet) {
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: CONTAINER_MP4\n";
|
"container_type: CONTAINER_MP4\n";
|
||||||
|
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kTestMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
EXPECT_FALSE(representation->Init());
|
EXPECT_FALSE(representation->Init());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,9 +509,8 @@ TEST_F(CommonMpdBuilderTest, InvalidMediaInfo) {
|
||||||
" pixel_height: 1\n"
|
" pixel_height: 1\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kTestMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
EXPECT_FALSE(representation->Init());
|
EXPECT_FALSE(representation->Init());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,9 +527,8 @@ TEST_F(CommonMpdBuilderTest, CheckVideoInfoReflectedInXml) {
|
||||||
" pixel_height: 1\n"
|
" pixel_height: 1\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kTestMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
@ -559,7 +557,7 @@ TEST_F(CommonMpdBuilderTest, CheckVideoInfoVp8CodecInMp4) {
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfoCodecVp8),
|
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfoCodecVp8),
|
||||||
MpdOptions(), kAnyRepresentationId, NoListener());
|
kAnyRepresentationId, NoListener());
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
@ -582,7 +580,7 @@ TEST_F(CommonMpdBuilderTest, CheckVideoInfoVp8CodecInWebm) {
|
||||||
"container_type: 3\n";
|
"container_type: 3\n";
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfoCodecVp8),
|
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfoCodecVp8),
|
||||||
MpdOptions(), kAnyRepresentationId, NoListener());
|
kAnyRepresentationId, NoListener());
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
@ -605,7 +603,7 @@ TEST_F(CommonMpdBuilderTest, CheckVideoInfoVp9CodecInWebm) {
|
||||||
"container_type: 3\n";
|
"container_type: 3\n";
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfoCodecVp9),
|
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfoCodecVp9),
|
||||||
MpdOptions(), kAnyRepresentationId, NoListener());
|
kAnyRepresentationId, NoListener());
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
xml::scoped_xml_ptr<xmlNode> node_xml(representation->GetXml());
|
||||||
EXPECT_NO_FATAL_FAILURE(
|
EXPECT_NO_FATAL_FAILURE(
|
||||||
|
@ -635,7 +633,7 @@ TEST_F(CommonMpdBuilderTest,
|
||||||
EXPECT_CALL(*listener,
|
EXPECT_CALL(*listener,
|
||||||
OnNewSegmentForRepresentation(kStartTime, kDuration));
|
OnNewSegmentForRepresentation(kStartTime, kDuration));
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo),
|
||||||
kAnyRepresentationId, std::move(listener));
|
kAnyRepresentationId, std::move(listener));
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
|
|
||||||
|
@ -666,7 +664,7 @@ TEST_F(CommonMpdBuilderTest,
|
||||||
EXPECT_CALL(*listener,
|
EXPECT_CALL(*listener,
|
||||||
OnSetFrameRateForRepresentation(kFrameDuration, kTimeScale));
|
OnSetFrameRateForRepresentation(kFrameDuration, kTimeScale));
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo),
|
||||||
kAnyRepresentationId, std::move(listener));
|
kAnyRepresentationId, std::move(listener));
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
|
|
||||||
|
@ -690,8 +688,7 @@ TEST_F(CommonMpdBuilderTest, CheckAdaptationSetVideoContentType) {
|
||||||
"container_type: CONTAINER_MP4\n";
|
"container_type: CONTAINER_MP4\n";
|
||||||
|
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(kVideoMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(kVideoMediaInfo));
|
||||||
|
|
||||||
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
||||||
|
@ -712,8 +709,7 @@ TEST_F(CommonMpdBuilderTest, CheckAdaptationSetAudioContentType) {
|
||||||
"container_type: CONTAINER_MP4\n";
|
"container_type: CONTAINER_MP4\n";
|
||||||
|
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(kAudioMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(kAudioMediaInfo));
|
||||||
|
|
||||||
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
||||||
|
@ -732,8 +728,7 @@ TEST_F(CommonMpdBuilderTest, CheckAdaptationSetTextContentType) {
|
||||||
"container_type: CONTAINER_TEXT\n";
|
"container_type: CONTAINER_TEXT\n";
|
||||||
|
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(kTextMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(kTextMediaInfo));
|
||||||
|
|
||||||
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
||||||
|
@ -748,7 +743,7 @@ TEST_F(CommonMpdBuilderTest, TtmlXmlMimeType) {
|
||||||
"container_type: CONTAINER_TEXT\n";
|
"container_type: CONTAINER_TEXT\n";
|
||||||
|
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTtmlXmlMediaInfo), MpdOptions(),
|
CreateRepresentation(ConvertToMediaInfo(kTtmlXmlMediaInfo),
|
||||||
kAnyRepresentationId, NoListener());
|
kAnyRepresentationId, NoListener());
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
||||||
|
@ -763,7 +758,7 @@ TEST_F(CommonMpdBuilderTest, TtmlMp4MimeType) {
|
||||||
"container_type: CONTAINER_MP4\n";
|
"container_type: CONTAINER_MP4\n";
|
||||||
|
|
||||||
auto representation =
|
auto representation =
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTtmlMp4MediaInfo), MpdOptions(),
|
CreateRepresentation(ConvertToMediaInfo(kTtmlMp4MediaInfo),
|
||||||
kAnyRepresentationId, NoListener());
|
kAnyRepresentationId, NoListener());
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
||||||
|
@ -777,9 +772,8 @@ TEST_F(CommonMpdBuilderTest, WebVttMimeType) {
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: CONTAINER_TEXT\n";
|
"container_type: CONTAINER_TEXT\n";
|
||||||
|
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kWebVttMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kWebVttMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
EXPECT_NO_FATAL_FAILURE(ExpectAttributeEqString(
|
||||||
"mimeType", "text/vtt", representation->GetXml().get()));
|
"mimeType", "text/vtt", representation->GetXml().get()));
|
||||||
|
@ -796,8 +790,7 @@ TEST_F(CommonMpdBuilderTest, CheckLanguageAttributeSet) {
|
||||||
"container_type: CONTAINER_TEXT\n";
|
"container_type: CONTAINER_TEXT\n";
|
||||||
|
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "en", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "en", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(kTextMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(kTextMediaInfo));
|
||||||
|
|
||||||
xml::scoped_xml_ptr<xmlNode> node_xml(adaptation_set->GetXml());
|
xml::scoped_xml_ptr<xmlNode> node_xml(adaptation_set->GetXml());
|
||||||
|
@ -818,8 +811,7 @@ TEST_F(CommonMpdBuilderTest, CheckConvertLanguageWithSubtag) {
|
||||||
// "por-BR" is the long tag for Brazillian Portuguese. The short tag
|
// "por-BR" is the long tag for Brazillian Portuguese. The short tag
|
||||||
// is "pt-BR", which is what should appear in the manifest.
|
// is "pt-BR", which is what should appear in the manifest.
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "por-BR", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "por-BR", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(kTextMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(kTextMediaInfo));
|
||||||
|
|
||||||
xml::scoped_xml_ptr<xmlNode> node_xml(adaptation_set->GetXml());
|
xml::scoped_xml_ptr<xmlNode> node_xml(adaptation_set->GetXml());
|
||||||
|
@ -831,14 +823,13 @@ TEST_F(CommonMpdBuilderTest, CheckAdaptationSetId) {
|
||||||
base::AtomicSequenceNumber sequence_counter;
|
base::AtomicSequenceNumber sequence_counter;
|
||||||
const uint32_t kAdaptationSetId = 42;
|
const uint32_t kAdaptationSetId = 42;
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kAdaptationSetId, adaptation_set.get()));
|
ASSERT_NO_FATAL_FAILURE(CheckIdEqual(kAdaptationSetId, adaptation_set.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify AdaptationSet::AddRole() works for "main" role.
|
// Verify AdaptationSet::AddRole() works for "main" role.
|
||||||
TEST_F(CommonMpdBuilderTest, AdaptationAddRoleElementMain) {
|
TEST_F(CommonMpdBuilderTest, AdaptationAddRoleElementMain) {
|
||||||
MpdBuilder mpd_builder(MpdBuilder::kStatic, MpdOptions());
|
MpdBuilder mpd_builder(MpdOptions{});
|
||||||
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
|
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
|
||||||
|
|
||||||
adaptation_set->AddRole(AdaptationSet::kRoleMain);
|
adaptation_set->AddRole(AdaptationSet::kRoleMain);
|
||||||
|
@ -851,8 +842,8 @@ TEST_F(CommonMpdBuilderTest, AdaptationAddRoleElementMain) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\"\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"
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\"\n"
|
||||||
" mediaPresentationDuration=\"PT0S\">\n"
|
" mediaPresentationDuration=\"PT0S\">\n"
|
||||||
" <Period id=\"0\">\n"
|
" <Period id=\"0\">\n"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"\">\n"
|
" <AdaptationSet id=\"0\" contentType=\"\">\n"
|
||||||
|
@ -871,7 +862,7 @@ TEST_F(CommonMpdBuilderTest, AdaptationAddRoleElementMain) {
|
||||||
// Add Role, ContentProtection, and Representation elements. Verify that
|
// Add Role, ContentProtection, and Representation elements. Verify that
|
||||||
// ContentProtection -> Role -> Representation are in order.
|
// ContentProtection -> Role -> Representation are in order.
|
||||||
TEST_F(CommonMpdBuilderTest, CheckContentProtectionRoleRepresentationOrder) {
|
TEST_F(CommonMpdBuilderTest, CheckContentProtectionRoleRepresentationOrder) {
|
||||||
MpdBuilder mpd_builder(MpdBuilder::kStatic, MpdOptions());
|
MpdBuilder mpd_builder(MpdOptions{});
|
||||||
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
|
AdaptationSet* adaptation_set = mpd_builder.AddAdaptationSet("");
|
||||||
adaptation_set->AddRole(AdaptationSet::kRoleMain);
|
adaptation_set->AddRole(AdaptationSet::kRoleMain);
|
||||||
ContentProtectionElement any_content_protection;
|
ContentProtectionElement any_content_protection;
|
||||||
|
@ -894,8 +885,8 @@ TEST_F(CommonMpdBuilderTest, CheckContentProtectionRoleRepresentationOrder) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\"\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"
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\"\n"
|
||||||
" mediaPresentationDuration=\"PT0S\">\n"
|
" mediaPresentationDuration=\"PT0S\">\n"
|
||||||
" <Period id=\"0\">\n"
|
" <Period id=\"0\">\n"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"audio\">\n"
|
" <AdaptationSet id=\"0\" contentType=\"audio\">\n"
|
||||||
|
@ -1024,8 +1015,7 @@ TEST_F(CommonMpdBuilderTest,
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
|
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
Representation* representation_480p =
|
Representation* representation_480p =
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(k480pMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(k480pMediaInfo));
|
||||||
Representation* representation_360p =
|
Representation* representation_360p =
|
||||||
|
@ -1250,9 +1240,8 @@ TEST_F(CommonMpdBuilderTest, SuppressRepresentationAttributes) {
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
|
|
||||||
auto representation =
|
auto representation = CreateRepresentation(
|
||||||
CreateRepresentation(ConvertToMediaInfo(kTestMediaInfo), MpdOptions(),
|
ConvertToMediaInfo(kTestMediaInfo), kAnyRepresentationId, NoListener());
|
||||||
kAnyRepresentationId, NoListener());
|
|
||||||
|
|
||||||
representation->SuppressOnce(Representation::kSuppressWidth);
|
representation->SuppressOnce(Representation::kSuppressWidth);
|
||||||
xml::scoped_xml_ptr<xmlNode> no_width(representation->GetXml());
|
xml::scoped_xml_ptr<xmlNode> no_width(representation->GetXml());
|
||||||
|
@ -1382,7 +1371,7 @@ TEST_F(CommonMpdBuilderTest, BubbleUpAttributesToAdaptationSet) {
|
||||||
// Also checking that not all Representations have to be added before calling
|
// Also checking that not all Representations have to be added before calling
|
||||||
// AddNewSegment() on a Representation.
|
// AddNewSegment() on a Representation.
|
||||||
// The output MPD's schema is checked at the very end.
|
// The output MPD's schema is checked at the very end.
|
||||||
TEST_F(StaticMpdBuilderTest, SubsegmentAlignment) {
|
TEST_F(OnDemandMpdBuilderTest, SubsegmentAlignment) {
|
||||||
base::AtomicSequenceNumber sequence_counter;
|
base::AtomicSequenceNumber sequence_counter;
|
||||||
const char k480pMediaInfo[] =
|
const char k480pMediaInfo[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
|
@ -1448,7 +1437,7 @@ TEST_F(StaticMpdBuilderTest, SubsegmentAlignment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that subsegmentAlignment can be force set to true.
|
// Verify that subsegmentAlignment can be force set to true.
|
||||||
TEST_F(StaticMpdBuilderTest, ForceSetsubsegmentAlignment) {
|
TEST_F(OnDemandMpdBuilderTest, ForceSetsubsegmentAlignment) {
|
||||||
base::AtomicSequenceNumber sequence_counter;
|
base::AtomicSequenceNumber sequence_counter;
|
||||||
const char k480pMediaInfo[] =
|
const char k480pMediaInfo[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
|
@ -1472,9 +1461,9 @@ TEST_F(StaticMpdBuilderTest, ForceSetsubsegmentAlignment) {
|
||||||
" pixel_height: 1\n"
|
" pixel_height: 1\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
|
MpdOptions mpd_options;
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
Representation* representation_480p =
|
Representation* representation_480p =
|
||||||
adaptation_set->AddRepresentation(ConvertToMediaInfo(k480pMediaInfo));
|
adaptation_set->AddRepresentation(ConvertToMediaInfo(k480pMediaInfo));
|
||||||
Representation* representation_360p =
|
Representation* representation_360p =
|
||||||
|
@ -1502,7 +1491,7 @@ TEST_F(StaticMpdBuilderTest, ForceSetsubsegmentAlignment) {
|
||||||
// Verify that segmentAlignment is set to true if all the Representations
|
// Verify that segmentAlignment is set to true if all the Representations
|
||||||
// segments' are aligned and the MPD type is dynamic.
|
// segments' are aligned and the MPD type is dynamic.
|
||||||
// The output MPD's schema is checked at the very end.
|
// The output MPD's schema is checked at the very end.
|
||||||
TEST_F(DynamicMpdBuilderTest, SegmentAlignment) {
|
TEST_F(LiveMpdBuilderTest, SegmentAlignment) {
|
||||||
base::AtomicSequenceNumber sequence_counter;
|
base::AtomicSequenceNumber sequence_counter;
|
||||||
const char k480pMediaInfo[] =
|
const char k480pMediaInfo[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
|
@ -1559,7 +1548,7 @@ TEST_F(DynamicMpdBuilderTest, SegmentAlignment) {
|
||||||
|
|
||||||
// Verify that the width and height attribute are set if all the video
|
// Verify that the width and height attribute are set if all the video
|
||||||
// representations have the same width and height.
|
// representations have the same width and height.
|
||||||
TEST_F(StaticMpdBuilderTest, AdapatationSetWidthAndHeight) {
|
TEST_F(OnDemandMpdBuilderTest, AdapatationSetWidthAndHeight) {
|
||||||
// Both 720p.
|
// Both 720p.
|
||||||
const char kVideoMediaInfo1[] =
|
const char kVideoMediaInfo1[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
|
@ -1600,7 +1589,7 @@ TEST_F(StaticMpdBuilderTest, AdapatationSetWidthAndHeight) {
|
||||||
|
|
||||||
// Verify that the maxWidth and maxHeight attribute are set if there are
|
// Verify that the maxWidth and maxHeight attribute are set if there are
|
||||||
// multiple video resolutions.
|
// multiple video resolutions.
|
||||||
TEST_F(StaticMpdBuilderTest, AdapatationSetMaxWidthAndMaxHeight) {
|
TEST_F(OnDemandMpdBuilderTest, AdapatationSetMaxWidthAndMaxHeight) {
|
||||||
const char kVideoMediaInfo1080p[] =
|
const char kVideoMediaInfo1080p[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
" codec: \"avc1\"\n"
|
" codec: \"avc1\"\n"
|
||||||
|
@ -1642,8 +1631,8 @@ 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;
|
||||||
|
|
||||||
auto representation = CreateRepresentation(video_media_info, MpdOptions(),
|
auto representation =
|
||||||
kRepresentationId, NoListener());
|
CreateRepresentation(video_media_info, kRepresentationId, NoListener());
|
||||||
EXPECT_TRUE(representation->Init());
|
EXPECT_TRUE(representation->Init());
|
||||||
ASSERT_NO_FATAL_FAILURE(
|
ASSERT_NO_FATAL_FAILURE(
|
||||||
CheckIdEqual(kRepresentationId, representation.get()));
|
CheckIdEqual(kRepresentationId, representation.get()));
|
||||||
|
@ -1664,8 +1653,7 @@ TEST_F(CommonMpdBuilderTest, SetSampleDuration) {
|
||||||
|
|
||||||
base::AtomicSequenceNumber sequence_counter;
|
base::AtomicSequenceNumber sequence_counter;
|
||||||
auto adaptation_set =
|
auto adaptation_set =
|
||||||
CreateAdaptationSet(kAnyAdaptationSetId, "", MpdOptions(),
|
CreateAdaptationSet(kAnyAdaptationSetId, "", &sequence_counter);
|
||||||
MpdBuilder::kStatic, &sequence_counter);
|
|
||||||
|
|
||||||
const MediaInfo video_media_info = ConvertToMediaInfo(kVideoMediaInfo);
|
const MediaInfo video_media_info = ConvertToMediaInfo(kVideoMediaInfo);
|
||||||
Representation* representation =
|
Representation* representation =
|
||||||
|
@ -1716,8 +1704,8 @@ TEST_F(CommonMpdBuilderTest, AdaptationSetAddContentProtectionAndUpdate) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
||||||
" minBufferTime=\"PT2S\" type=\"static\""
|
|
||||||
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\""
|
||||||
" mediaPresentationDuration=\"PT0S\">"
|
" mediaPresentationDuration=\"PT0S\">"
|
||||||
" <Period id=\"0\">"
|
" <Period id=\"0\">"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
||||||
|
@ -1745,8 +1733,8 @@ TEST_F(CommonMpdBuilderTest, AdaptationSetAddContentProtectionAndUpdate) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
||||||
" minBufferTime=\"PT2S\" type=\"static\""
|
|
||||||
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\""
|
||||||
" mediaPresentationDuration=\"PT0S\">"
|
" mediaPresentationDuration=\"PT0S\">"
|
||||||
" <Period id=\"0\">"
|
" <Period id=\"0\">"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
||||||
|
@ -1800,8 +1788,8 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
||||||
" minBufferTime=\"PT2S\" type=\"static\""
|
|
||||||
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\""
|
||||||
" mediaPresentationDuration=\"PT0S\">"
|
" mediaPresentationDuration=\"PT0S\">"
|
||||||
" <Period id=\"0\">"
|
" <Period id=\"0\">"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
||||||
|
@ -1829,8 +1817,8 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
||||||
" minBufferTime=\"PT2S\" type=\"static\""
|
|
||||||
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\""
|
||||||
" mediaPresentationDuration=\"PT0S\">"
|
" mediaPresentationDuration=\"PT0S\">"
|
||||||
" <Period id=\"0\">"
|
" <Period id=\"0\">"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
|
||||||
|
@ -1853,13 +1841,13 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add one video check the output.
|
// Add one video check the output.
|
||||||
TEST_F(StaticMpdBuilderTest, Video) {
|
TEST_F(OnDemandMpdBuilderTest, Video) {
|
||||||
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
ASSERT_NO_FATAL_FAILURE(AddRepresentation(video_media_info));
|
ASSERT_NO_FATAL_FAILURE(AddRepresentation(video_media_info));
|
||||||
EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputVideo1));
|
EXPECT_NO_FATAL_FAILURE(CheckMpd(kFileNameExpectedMpdOutputVideo1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StaticMpdBuilderTest, TwoVideosWithDifferentResolutions) {
|
TEST_F(OnDemandMpdBuilderTest, TwoVideosWithDifferentResolutions) {
|
||||||
AdaptationSet* adaptation_set = mpd_.AddAdaptationSet("");
|
AdaptationSet* adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
|
|
||||||
MediaInfo media_info1 = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
MediaInfo media_info1 = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
|
@ -1872,7 +1860,7 @@ TEST_F(StaticMpdBuilderTest, TwoVideosWithDifferentResolutions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add both video and audio and check the output.
|
// Add both video and audio and check the output.
|
||||||
TEST_F(StaticMpdBuilderTest, VideoAndAudio) {
|
TEST_F(OnDemandMpdBuilderTest, VideoAndAudio) {
|
||||||
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
MediaInfo audio_media_info = GetTestMediaInfo(kFileNameAudioMediaInfo1);
|
MediaInfo audio_media_info = GetTestMediaInfo(kFileNameAudioMediaInfo1);
|
||||||
|
|
||||||
|
@ -1897,7 +1885,7 @@ TEST_F(StaticMpdBuilderTest, VideoAndAudio) {
|
||||||
// MPD schema has strict ordering. AudioChannelConfiguration must appear before
|
// MPD schema has strict ordering. AudioChannelConfiguration must appear before
|
||||||
// ContentProtection.
|
// ContentProtection.
|
||||||
// Also test that Representation::AddContentProtection() works.
|
// Also test that Representation::AddContentProtection() works.
|
||||||
TEST_F(StaticMpdBuilderTest, AudioChannelConfigurationWithContentProtection) {
|
TEST_F(OnDemandMpdBuilderTest, AudioChannelConfigurationWithContentProtection) {
|
||||||
const char kTestMediaInfo[] =
|
const char kTestMediaInfo[] =
|
||||||
"bandwidth: 195857\n"
|
"bandwidth: 195857\n"
|
||||||
"audio_info {\n"
|
"audio_info {\n"
|
||||||
|
@ -1926,8 +1914,8 @@ TEST_F(StaticMpdBuilderTest, AudioChannelConfigurationWithContentProtection) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
||||||
" minBufferTime=\"PT2S\" type=\"static\""
|
|
||||||
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\""
|
||||||
" mediaPresentationDuration=\"PT24.0094S\">"
|
" mediaPresentationDuration=\"PT24.0094S\">"
|
||||||
" <Period id=\"0\">"
|
" <Period id=\"0\">"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"audio\">"
|
" <AdaptationSet id=\"0\" contentType=\"audio\">"
|
||||||
|
@ -1972,7 +1960,7 @@ TEST_F(StaticMpdBuilderTest, AudioChannelConfigurationWithContentProtection) {
|
||||||
|
|
||||||
// Static profile requires bandwidth to be set because it has no other way to
|
// Static profile requires bandwidth to be set because it has no other way to
|
||||||
// get the bandwidth for the Representation.
|
// get the bandwidth for the Representation.
|
||||||
TEST_F(StaticMpdBuilderTest, MediaInfoMissingBandwidth) {
|
TEST_F(OnDemandMpdBuilderTest, MediaInfoMissingBandwidth) {
|
||||||
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
video_media_info.clear_bandwidth();
|
video_media_info.clear_bandwidth();
|
||||||
AddRepresentation(video_media_info);
|
AddRepresentation(video_media_info);
|
||||||
|
@ -1981,7 +1969,7 @@ TEST_F(StaticMpdBuilderTest, MediaInfoMissingBandwidth) {
|
||||||
ASSERT_FALSE(mpd_.ToString(&mpd_doc));
|
ASSERT_FALSE(mpd_.ToString(&mpd_doc));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StaticMpdBuilderTest, WriteToFile) {
|
TEST_F(OnDemandMpdBuilderTest, WriteToFile) {
|
||||||
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
MediaInfo video_media_info = GetTestMediaInfo(kFileNameVideoMediaInfo1);
|
||||||
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
AdaptationSet* video_adaptation_set = mpd_.AddAdaptationSet("");
|
||||||
ASSERT_TRUE(video_adaptation_set);
|
ASSERT_TRUE(video_adaptation_set);
|
||||||
|
@ -2007,7 +1995,7 @@ TEST_F(StaticMpdBuilderTest, WriteToFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that a text path works.
|
// Verify that a text path works.
|
||||||
TEST_F(StaticMpdBuilderTest, Text) {
|
TEST_F(OnDemandMpdBuilderTest, Text) {
|
||||||
const char kTextMediaInfo[] =
|
const char kTextMediaInfo[] =
|
||||||
"text_info {\n"
|
"text_info {\n"
|
||||||
" format: 'ttml'\n"
|
" format: 'ttml'\n"
|
||||||
|
@ -2026,8 +2014,8 @@ TEST_F(StaticMpdBuilderTest, Text) {
|
||||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\""
|
||||||
" minBufferTime=\"PT2S\" type=\"static\""
|
|
||||||
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
|
||||||
|
" minBufferTime=\"PT2S\" type=\"static\""
|
||||||
" mediaPresentationDuration=\"PT35S\">"
|
" mediaPresentationDuration=\"PT35S\">"
|
||||||
" <Period id=\"0\">"
|
" <Period id=\"0\">"
|
||||||
" <AdaptationSet id=\"0\" contentType=\"text\" lang=\"en\">"
|
" <AdaptationSet id=\"0\" contentType=\"text\" lang=\"en\">"
|
||||||
|
@ -2057,7 +2045,7 @@ TEST_F(StaticMpdBuilderTest, Text) {
|
||||||
// Check whether the attributes are set correctly for dynamic <MPD> element.
|
// Check whether the attributes are set correctly for dynamic <MPD> element.
|
||||||
// This test must use ASSERT_EQ for comparison because XmlEqual() cannot
|
// This test must use ASSERT_EQ for comparison because XmlEqual() cannot
|
||||||
// handle namespaces correctly yet.
|
// handle namespaces correctly yet.
|
||||||
TEST_F(DynamicMpdBuilderTest, CheckMpdAttributes) {
|
TEST_F(LiveMpdBuilderTest, DynamicCheckMpdAttributes) {
|
||||||
static const char kExpectedOutput[] =
|
static const char kExpectedOutput[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<!--Generated with https://github.com/google/shaka-packager "
|
"<!--Generated with https://github.com/google/shaka-packager "
|
||||||
|
@ -2068,15 +2056,40 @@ TEST_F(DynamicMpdBuilderTest, CheckMpdAttributes) {
|
||||||
"xsi:schemaLocation="
|
"xsi:schemaLocation="
|
||||||
"\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
|
"\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
|
||||||
"xmlns:cenc=\"urn:mpeg:cenc:2013\" "
|
"xmlns:cenc=\"urn:mpeg:cenc:2013\" "
|
||||||
|
"profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
||||||
"minBufferTime=\"PT2S\" "
|
"minBufferTime=\"PT2S\" "
|
||||||
"type=\"dynamic\" "
|
"type=\"dynamic\" "
|
||||||
"profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
|
||||||
"publishTime=\"2016-01-11T15:10:24Z\" "
|
"publishTime=\"2016-01-11T15:10:24Z\" "
|
||||||
"availabilityStartTime=\"2011-12-25T12:30:00\">\n"
|
"availabilityStartTime=\"2011-12-25T12:30:00\">\n"
|
||||||
" <Period id=\"0\" start=\"PT0S\"/>\n"
|
" <Period id=\"0\" start=\"PT0S\"/>\n"
|
||||||
"</MPD>\n";
|
"</MPD>\n";
|
||||||
|
|
||||||
std::string mpd_doc;
|
std::string mpd_doc;
|
||||||
|
mutable_mpd_options()->mpd_type = MpdType::kDynamic;
|
||||||
|
ASSERT_TRUE(mpd_.ToString(&mpd_doc));
|
||||||
|
ASSERT_EQ(kExpectedOutput, mpd_doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LiveMpdBuilderTest, StaticCheckMpdAttributes) {
|
||||||
|
static const char kExpectedOutput[] =
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<!--Generated with https://github.com/google/shaka-packager "
|
||||||
|
"version <tag>-<hash>-<test>-->\n"
|
||||||
|
"<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\" "
|
||||||
|
"xmlns:cenc=\"urn:mpeg:cenc:2013\" "
|
||||||
|
"profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
|
||||||
|
"minBufferTime=\"PT2S\" "
|
||||||
|
"type=\"static\" "
|
||||||
|
"mediaPresentationDuration=\"PT0S\">\n"
|
||||||
|
" <Period id=\"0\"/>\n"
|
||||||
|
"</MPD>\n";
|
||||||
|
|
||||||
|
std::string mpd_doc;
|
||||||
|
mutable_mpd_options()->mpd_type = MpdType::kStatic;
|
||||||
ASSERT_TRUE(mpd_.ToString(&mpd_doc));
|
ASSERT_TRUE(mpd_.ToString(&mpd_doc));
|
||||||
ASSERT_EQ(kExpectedOutput, mpd_doc);
|
ASSERT_EQ(kExpectedOutput, mpd_doc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,24 +15,20 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "packager/base/macros.h"
|
#include "packager/base/macros.h"
|
||||||
|
#include "packager/mpd/base/mpd_options.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
|
||||||
class MediaInfo;
|
class MediaInfo;
|
||||||
struct ContentProtectionElement;
|
struct ContentProtectionElement;
|
||||||
|
|
||||||
enum DashProfile {
|
|
||||||
kUnknownProfile,
|
|
||||||
kOnDemandProfile,
|
|
||||||
kLiveProfile,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Interface for publish/subscribe publisher class which notifies MpdBuilder
|
/// Interface for publish/subscribe publisher class which notifies MpdBuilder
|
||||||
/// of media-related events.
|
/// of media-related events.
|
||||||
class MpdNotifier {
|
class MpdNotifier {
|
||||||
public:
|
public:
|
||||||
MpdNotifier(DashProfile dash_profile) : dash_profile_(dash_profile) {};
|
explicit MpdNotifier(const MpdOptions& mpd_options)
|
||||||
virtual ~MpdNotifier() {};
|
: mpd_options_(mpd_options) {}
|
||||||
|
virtual ~MpdNotifier() {}
|
||||||
|
|
||||||
/// Initializes the notifier. For example, if this notifier uses a network for
|
/// Initializes the notifier. For example, if this notifier uses a network for
|
||||||
/// notification, then this would set up the connection with the remote host.
|
/// notification, then this would set up the connection with the remote host.
|
||||||
|
@ -105,10 +101,13 @@ class MpdNotifier {
|
||||||
virtual bool Flush() = 0;
|
virtual bool Flush() = 0;
|
||||||
|
|
||||||
/// @return The dash profile for this object.
|
/// @return The dash profile for this object.
|
||||||
DashProfile dash_profile() const { return dash_profile_; }
|
DashProfile dash_profile() const { return mpd_options_.dash_profile; }
|
||||||
|
|
||||||
|
/// @return The mpd type for this object.
|
||||||
|
MpdType mpd_type() const { return mpd_options_.mpd_type; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const DashProfile dash_profile_;
|
const MpdOptions mpd_options_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MpdNotifier);
|
DISALLOW_COPY_AND_ASSIGN(MpdNotifier);
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,27 +11,27 @@
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
|
||||||
|
enum class DashProfile {
|
||||||
|
kUnknown,
|
||||||
|
kOnDemand,
|
||||||
|
kLive,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MpdType { kStatic, kDynamic };
|
||||||
|
|
||||||
/// Defines Mpd Options.
|
/// Defines Mpd Options.
|
||||||
struct MpdOptions {
|
struct MpdOptions {
|
||||||
MpdOptions()
|
DashProfile dash_profile = DashProfile::kOnDemand;
|
||||||
: availability_time_offset(0),
|
MpdType mpd_type = MpdType::kStatic;
|
||||||
minimum_update_period(0),
|
double availability_time_offset = 0;
|
||||||
|
double minimum_update_period = 0;
|
||||||
// TODO(tinskip): Set min_buffer_time in unit tests rather than here.
|
// TODO(tinskip): Set min_buffer_time in unit tests rather than here.
|
||||||
min_buffer_time(2.0),
|
double min_buffer_time = 2.0;
|
||||||
time_shift_buffer_depth(0),
|
double time_shift_buffer_depth = 0;
|
||||||
suggested_presentation_delay(0) {}
|
double suggested_presentation_delay = 0;
|
||||||
|
|
||||||
~MpdOptions() {};
|
|
||||||
|
|
||||||
double availability_time_offset;
|
|
||||||
double minimum_update_period;
|
|
||||||
double min_buffer_time;
|
|
||||||
double time_shift_buffer_depth;
|
|
||||||
double suggested_presentation_delay;
|
|
||||||
std::string default_language;
|
std::string default_language;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
||||||
#endif // MPD_BASE_MPD_OPTIONS_H_
|
#endif // MPD_BASE_MPD_OPTIONS_H_
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,12 @@
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
|
||||||
SimpleMpdNotifier::SimpleMpdNotifier(DashProfile dash_profile,
|
SimpleMpdNotifier::SimpleMpdNotifier(const MpdOptions& mpd_options,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path)
|
const std::string& output_path)
|
||||||
: MpdNotifier(dash_profile),
|
: MpdNotifier(mpd_options),
|
||||||
output_path_(output_path),
|
output_path_(output_path),
|
||||||
mpd_builder_(new MpdBuilder(dash_profile == kLiveProfile
|
mpd_builder_(new MpdBuilder(mpd_options)) {
|
||||||
? MpdBuilder::kDynamic
|
|
||||||
: MpdBuilder::kStatic,
|
|
||||||
mpd_options)) {
|
|
||||||
DCHECK(dash_profile == kLiveProfile || dash_profile == kOnDemandProfile);
|
|
||||||
for (size_t i = 0; i < base_urls.size(); ++i)
|
for (size_t i = 0; i < base_urls.size(); ++i)
|
||||||
mpd_builder_->AddBaseUrl(base_urls[i]);
|
mpd_builder_->AddBaseUrl(base_urls[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ struct MpdOptions;
|
||||||
/// generates an Mpd file.
|
/// generates an Mpd file.
|
||||||
class SimpleMpdNotifier : public MpdNotifier {
|
class SimpleMpdNotifier : public MpdNotifier {
|
||||||
public:
|
public:
|
||||||
SimpleMpdNotifier(DashProfile dash_profile,
|
SimpleMpdNotifier(const MpdOptions& mpd_options,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path);
|
const std::string& output_path);
|
||||||
~SimpleMpdNotifier() override;
|
~SimpleMpdNotifier() override;
|
||||||
|
|
|
@ -35,8 +35,7 @@ const char kValidMediaInfo[] =
|
||||||
const uint32_t kDefaultAdaptationSetId = 0u;
|
const uint32_t kDefaultAdaptationSetId = 0u;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class SimpleMpdNotifierTest
|
class SimpleMpdNotifierTest : public ::testing::Test {
|
||||||
: public ::testing::TestWithParam<MpdBuilder::MpdType> {
|
|
||||||
protected:
|
protected:
|
||||||
SimpleMpdNotifierTest()
|
SimpleMpdNotifierTest()
|
||||||
: default_mock_adaptation_set_(
|
: default_mock_adaptation_set_(
|
||||||
|
@ -51,20 +50,6 @@ class SimpleMpdNotifierTest
|
||||||
base::DeleteFile(temp_file_path_, false /* non recursive, just 1 file */);
|
base::DeleteFile(temp_file_path_, false /* non recursive, just 1 file */);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MockMpdBuilder> StaticMpdBuilderMock() {
|
|
||||||
return std::unique_ptr<MockMpdBuilder>(
|
|
||||||
new MockMpdBuilder(MpdBuilder::kStatic));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<MockMpdBuilder> DynamicMpdBuilderMock() {
|
|
||||||
return std::unique_ptr<MockMpdBuilder>(
|
|
||||||
new MockMpdBuilder(MpdBuilder::kDynamic));
|
|
||||||
}
|
|
||||||
|
|
||||||
MpdBuilder::MpdType GetMpdBuilderType(const SimpleMpdNotifier& notifier) {
|
|
||||||
return notifier.MpdBuilderForTesting()->type();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMpdBuilder(SimpleMpdNotifier* notifier,
|
void SetMpdBuilder(SimpleMpdNotifier* notifier,
|
||||||
std::unique_ptr<MpdBuilder> mpd_builder) {
|
std::unique_ptr<MpdBuilder> mpd_builder) {
|
||||||
notifier->SetMpdBuilderForTesting(std::move(mpd_builder));
|
notifier->SetMpdBuilderForTesting(std::move(mpd_builder));
|
||||||
|
@ -83,29 +68,12 @@ class SimpleMpdNotifierTest
|
||||||
base::FilePath temp_file_path_;
|
base::FilePath temp_file_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Verify that it creates the correct MpdBuilder type using DashProfile passed
|
|
||||||
// to the constructor.
|
|
||||||
TEST_F(SimpleMpdNotifierTest, CreateCorrectMpdBuilderType) {
|
|
||||||
SimpleMpdNotifier on_demand_notifier(kOnDemandProfile, empty_mpd_option_,
|
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
EXPECT_TRUE(on_demand_notifier.Init());
|
|
||||||
EXPECT_EQ(MpdBuilder::kStatic,
|
|
||||||
GetMpdBuilderType(on_demand_notifier));
|
|
||||||
SimpleMpdNotifier live_notifier(kLiveProfile, empty_mpd_option_,
|
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
EXPECT_TRUE(live_notifier.Init());
|
|
||||||
EXPECT_EQ(MpdBuilder::kDynamic, GetMpdBuilderType(live_notifier));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify NotifyNewContainer() works as expected for VOD.
|
// Verify NotifyNewContainer() works as expected for VOD.
|
||||||
TEST_P(SimpleMpdNotifierTest, NotifyNewContainer) {
|
TEST_F(SimpleMpdNotifierTest, NotifyNewContainer) {
|
||||||
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
|
|
||||||
const uint32_t kRepresentationId = 1u;
|
const uint32_t kRepresentationId = 1u;
|
||||||
const MpdBuilder::MpdType mpd_type = GetParam();
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(
|
|
||||||
new MockMpdBuilder(mpd_type));
|
|
||||||
std::unique_ptr<MockRepresentation> mock_representation(
|
std::unique_ptr<MockRepresentation> mock_representation(
|
||||||
new MockRepresentation(kRepresentationId));
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
@ -125,44 +93,11 @@ TEST_P(SimpleMpdNotifierTest, NotifyNewContainer) {
|
||||||
EXPECT_TRUE(notifier.Flush());
|
EXPECT_TRUE(notifier.Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify NotifySampleDuration() works as expected for Live.
|
TEST_F(SimpleMpdNotifierTest, NotifySampleDuration) {
|
||||||
TEST_F(SimpleMpdNotifierTest, LiveNotifySampleDuration) {
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
SimpleMpdNotifier notifier(kLiveProfile, empty_mpd_option_, empty_base_urls_,
|
|
||||||
output_path_);
|
|
||||||
|
|
||||||
const uint32_t kRepresentationId = 8u;
|
const uint32_t kRepresentationId = 8u;
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(DynamicMpdBuilderMock());
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
std::unique_ptr<MockRepresentation> mock_representation(
|
|
||||||
new MockRepresentation(kRepresentationId));
|
|
||||||
|
|
||||||
EXPECT_CALL(*mock_mpd_builder, AddAdaptationSet(_))
|
|
||||||
.WillOnce(Return(default_mock_adaptation_set_.get()));
|
|
||||||
EXPECT_CALL(*default_mock_adaptation_set_, AddRepresentation(_))
|
|
||||||
.WillOnce(Return(mock_representation.get()));
|
|
||||||
|
|
||||||
uint32_t container_id;
|
|
||||||
SetMpdBuilder(¬ifier, std::move(mock_mpd_builder));
|
|
||||||
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
|
||||||
&container_id));
|
|
||||||
EXPECT_EQ(kRepresentationId, container_id);
|
|
||||||
|
|
||||||
const uint32_t kSampleDuration = 100;
|
|
||||||
EXPECT_CALL(*mock_representation, SetSampleDuration(kSampleDuration));
|
|
||||||
EXPECT_TRUE(
|
|
||||||
notifier.NotifySampleDuration(kRepresentationId, kSampleDuration));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that NotifySampleDuration works for OnDemand profile.
|
|
||||||
// TODO(rkuroiwa): SimpleMpdNotifier returns a container ID but does not
|
|
||||||
// register it to its map for VOD. Must fix and enable this test.
|
|
||||||
// This test can be also parmeterized just like NotifyNewContainer() test, once
|
|
||||||
// it is fixed.
|
|
||||||
TEST_F(SimpleMpdNotifierTest, OnDemandNotifySampleDuration) {
|
|
||||||
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
|
|
||||||
const uint32_t kRepresentationId = 14u;
|
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(StaticMpdBuilderMock());
|
|
||||||
std::unique_ptr<MockRepresentation> mock_representation(
|
std::unique_ptr<MockRepresentation> mock_representation(
|
||||||
new MockRepresentation(kRepresentationId));
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
@ -189,8 +124,7 @@ TEST_F(SimpleMpdNotifierTest, OnDemandNotifySampleDuration) {
|
||||||
// This issue identified a bug where using SimpleMpdNotifier with multiple
|
// This issue identified a bug where using SimpleMpdNotifier with multiple
|
||||||
// threads causes a deadlock.
|
// threads causes a deadlock.
|
||||||
TEST_F(SimpleMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
|
TEST_F(SimpleMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
|
||||||
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
uint32_t container_id;
|
uint32_t container_id;
|
||||||
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
EXPECT_TRUE(notifier.NotifyNewContainer(ConvertToMediaInfo(kValidMediaInfo),
|
||||||
&container_id));
|
&container_id));
|
||||||
|
@ -199,13 +133,11 @@ TEST_F(SimpleMpdNotifierTest, NotifyNewContainerAndSampleDurationNoMock) {
|
||||||
EXPECT_TRUE(notifier.Flush());
|
EXPECT_TRUE(notifier.Flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that NotifyNewSegment() for live works.
|
TEST_F(SimpleMpdNotifierTest, NotifyNewSegment) {
|
||||||
TEST_F(SimpleMpdNotifierTest, LiveNotifyNewSegment) {
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
SimpleMpdNotifier notifier(kLiveProfile, empty_mpd_option_, empty_base_urls_,
|
|
||||||
output_path_);
|
|
||||||
|
|
||||||
const uint32_t kRepresentationId = 447834u;
|
const uint32_t kRepresentationId = 447834u;
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(DynamicMpdBuilderMock());
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
std::unique_ptr<MockRepresentation> mock_representation(
|
std::unique_ptr<MockRepresentation> mock_representation(
|
||||||
new MockRepresentation(kRepresentationId));
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
@ -230,13 +162,11 @@ TEST_F(SimpleMpdNotifierTest, LiveNotifyNewSegment) {
|
||||||
kSegmentDuration, kSegmentSize));
|
kSegmentDuration, kSegmentSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify AddContentProtectionElement() works. Profile doesn't matter.
|
|
||||||
TEST_F(SimpleMpdNotifierTest, AddContentProtectionElement) {
|
TEST_F(SimpleMpdNotifierTest, AddContentProtectionElement) {
|
||||||
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
empty_base_urls_, output_path_);
|
|
||||||
|
|
||||||
const uint32_t kRepresentationId = 0u;
|
const uint32_t kRepresentationId = 0u;
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(StaticMpdBuilderMock());
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
std::unique_ptr<MockRepresentation> mock_representation(
|
std::unique_ptr<MockRepresentation> mock_representation(
|
||||||
new MockRepresentation(kRepresentationId));
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
@ -256,7 +186,7 @@ TEST_F(SimpleMpdNotifierTest, AddContentProtectionElement) {
|
||||||
EXPECT_TRUE(notifier.AddContentProtectionElement(kRepresentationId, element));
|
EXPECT_TRUE(notifier.AddContentProtectionElement(kRepresentationId, element));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(SimpleMpdNotifierTest, UpdateEncryption) {
|
TEST_F(SimpleMpdNotifierTest, UpdateEncryption) {
|
||||||
const char kProtectedContent[] =
|
const char kProtectedContent[] =
|
||||||
"video_info {\n"
|
"video_info {\n"
|
||||||
" codec: 'avc1'\n"
|
" codec: 'avc1'\n"
|
||||||
|
@ -276,10 +206,9 @@ TEST_P(SimpleMpdNotifierTest, UpdateEncryption) {
|
||||||
" default_key_id: '_default_key_id_'\n"
|
" default_key_id: '_default_key_id_'\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"container_type: 1\n";
|
"container_type: 1\n";
|
||||||
SimpleMpdNotifier notifier(kLiveProfile, empty_mpd_option_, empty_base_urls_,
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
output_path_);
|
|
||||||
const uint32_t kRepresentationId = 447834u;
|
const uint32_t kRepresentationId = 447834u;
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(DynamicMpdBuilderMock());
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
std::unique_ptr<MockRepresentation> mock_representation(
|
std::unique_ptr<MockRepresentation> mock_representation(
|
||||||
new MockRepresentation(kRepresentationId));
|
new MockRepresentation(kRepresentationId));
|
||||||
|
|
||||||
|
@ -312,7 +241,7 @@ TEST_P(SimpleMpdNotifierTest, UpdateEncryption) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't put different audio languages or codecs in the same AdaptationSet.
|
// Don't put different audio languages or codecs in the same AdaptationSet.
|
||||||
TEST_P(SimpleMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
TEST_F(SimpleMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
||||||
// MP4, English
|
// MP4, English
|
||||||
const char kAudioContent1[] =
|
const char kAudioContent1[] =
|
||||||
"audio_info {\n"
|
"audio_info {\n"
|
||||||
|
@ -365,9 +294,8 @@ TEST_P(SimpleMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
||||||
"container_type: CONTAINER_WEBM\n"
|
"container_type: CONTAINER_WEBM\n"
|
||||||
"media_duration_seconds: 10.5\n";
|
"media_duration_seconds: 10.5\n";
|
||||||
|
|
||||||
SimpleMpdNotifier notifier(kOnDemandProfile, empty_mpd_option_,
|
SimpleMpdNotifier notifier(empty_mpd_option_, empty_base_urls_, output_path_);
|
||||||
empty_base_urls_, output_path_);
|
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(new MockMpdBuilder());
|
||||||
std::unique_ptr<MockMpdBuilder> mock_mpd_builder(StaticMpdBuilderMock());
|
|
||||||
|
|
||||||
std::unique_ptr<MockAdaptationSet> adaptation_set1(new MockAdaptationSet(1));
|
std::unique_ptr<MockAdaptationSet> adaptation_set1(new MockAdaptationSet(1));
|
||||||
std::unique_ptr<MockAdaptationSet> adaptation_set2(new MockAdaptationSet(2));
|
std::unique_ptr<MockAdaptationSet> adaptation_set2(new MockAdaptationSet(2));
|
||||||
|
@ -410,9 +338,4 @@ TEST_P(SimpleMpdNotifierTest, SplitAdaptationSetsByLanguageAndCodec) {
|
||||||
ConvertToMediaInfo(kAudioContent4), &unused_container_id));
|
ConvertToMediaInfo(kAudioContent4), &unused_container_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(StaticAndDynamic,
|
|
||||||
SimpleMpdNotifierTest,
|
|
||||||
::testing::Values(MpdBuilder::kStatic,
|
|
||||||
MpdBuilder::kDynamic));
|
|
||||||
|
|
||||||
} // namespace shaka
|
} // namespace shaka
|
||||||
|
|
|
@ -35,12 +35,11 @@ class DashIopMpdNotifierFactory : public MpdNotifierFactory {
|
||||||
DashIopMpdNotifierFactory() {}
|
DashIopMpdNotifierFactory() {}
|
||||||
~DashIopMpdNotifierFactory() override {}
|
~DashIopMpdNotifierFactory() override {}
|
||||||
|
|
||||||
std::unique_ptr<MpdNotifier> Create(DashProfile dash_profile,
|
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path) override {
|
const std::string& output_path) override {
|
||||||
return std::unique_ptr<MpdNotifier>(new DashIopMpdNotifier(
|
return std::unique_ptr<MpdNotifier>(
|
||||||
dash_profile, mpd_options, base_urls, output_path));
|
new DashIopMpdNotifier(mpd_options, base_urls, output_path));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,12 +49,11 @@ class SimpleMpdNotifierFactory : public MpdNotifierFactory {
|
||||||
SimpleMpdNotifierFactory() {}
|
SimpleMpdNotifierFactory() {}
|
||||||
~SimpleMpdNotifierFactory() override {}
|
~SimpleMpdNotifierFactory() override {}
|
||||||
|
|
||||||
std::unique_ptr<MpdNotifier> Create(DashProfile dash_profile,
|
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path) override {
|
const std::string& output_path) override {
|
||||||
return std::unique_ptr<MpdNotifier>(new SimpleMpdNotifier(
|
return std::unique_ptr<MpdNotifier>(
|
||||||
dash_profile, mpd_options, base_urls, output_path));
|
new SimpleMpdNotifier(mpd_options, base_urls, output_path));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,8 +94,8 @@ void MpdWriter::AddBaseUrl(const std::string& base_url) {
|
||||||
|
|
||||||
bool MpdWriter::WriteMpdToFile(const char* file_name) {
|
bool MpdWriter::WriteMpdToFile(const char* file_name) {
|
||||||
CHECK(file_name);
|
CHECK(file_name);
|
||||||
std::unique_ptr<MpdNotifier> notifier = notifier_factory_->Create(
|
std::unique_ptr<MpdNotifier> notifier =
|
||||||
kOnDemandProfile, MpdOptions(), base_urls_, file_name);
|
notifier_factory_->Create(MpdOptions(), base_urls_, file_name);
|
||||||
if (!notifier->Init()) {
|
if (!notifier->Init()) {
|
||||||
LOG(ERROR) << "failed to initialize MpdNotifier.";
|
LOG(ERROR) << "failed to initialize MpdNotifier.";
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,7 +35,6 @@ class MpdNotifierFactory {
|
||||||
virtual ~MpdNotifierFactory() {}
|
virtual ~MpdNotifierFactory() {}
|
||||||
|
|
||||||
virtual std::unique_ptr<MpdNotifier> Create(
|
virtual std::unique_ptr<MpdNotifier> Create(
|
||||||
DashProfile dash_profile,
|
|
||||||
const MpdOptions& mpd_options,
|
const MpdOptions& mpd_options,
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path) = 0;
|
const std::string& output_path) = 0;
|
||||||
|
|
|
@ -33,14 +33,13 @@ class TestMpdNotifierFactory : public MpdNotifierFactory {
|
||||||
// std::unique_ptr.
|
// std::unique_ptr.
|
||||||
// For now we only need to return MockMpdNotifier() with these set of
|
// For now we only need to return MockMpdNotifier() with these set of
|
||||||
// expectations for all the tests.
|
// expectations for all the tests.
|
||||||
std::unique_ptr<MpdNotifier> Create(DashProfile dash_profile,
|
std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options,
|
||||||
const MpdOptions& mpd_options,
|
|
||||||
const std::vector<std::string>& base_urls,
|
const std::vector<std::string>& base_urls,
|
||||||
const std::string& output_path) override {
|
const std::string& output_path) override {
|
||||||
EXPECT_EQ(expected_base_urls_, base_urls);
|
EXPECT_EQ(expected_base_urls_, base_urls);
|
||||||
|
|
||||||
std::unique_ptr<MockMpdNotifier> mock_notifier(
|
std::unique_ptr<MockMpdNotifier> mock_notifier(
|
||||||
new MockMpdNotifier(kOnDemandProfile));
|
new MockMpdNotifier(mpd_options));
|
||||||
|
|
||||||
EXPECT_CALL(*mock_notifier, Init()).WillOnce(Return(true));
|
EXPECT_CALL(*mock_notifier, Init()).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*mock_notifier, NotifyNewContainer(_, _))
|
EXPECT_CALL(*mock_notifier, NotifyNewContainer(_, _))
|
||||||
|
|
Loading…
Reference in New Issue