Fix schematron validation problem for live

- From DASH spec 2014, MPD@publishTime and Period@id are required for
  'dynamic' MPD.
- Period@id is always set to "0".
- MPD@publishTime is set to the time when the MPD is output.

Issue #55

Change-Id: I5e50aa11067176e69a2343fbc82ca42129703e1b
This commit is contained in:
Rintaro Kuroiwa 2016-01-11 15:58:02 -08:00
parent 61a8d4f09e
commit 5ad076d92c
25 changed files with 121 additions and 54 deletions

View File

@ -449,18 +449,29 @@ class PackagerAppTest(unittest.TestCase):
self._DiffGold(test_output_prefix + '-%d.m4s' % i,
golden_file_name_prefix + '-%d.m4s' % i)
# Live mpd contains a current availabilityStartTime, which needs to be
# replaced for comparison.
# Live mpd contains current availabilityStartTime and publishTime, which
# needs to be replaced for comparison.
def _DiffLiveMpdGold(self, test_output, golden_file_name):
with open(test_output, 'r') as f:
content = f.read()
# Extract availabilityStartTime
m = re.search('(?<=availabilityStartTime=")[^"]+', content)
# Extract availabilityStartTime.
m = re.search('availabilityStartTime="[^"]+"', content)
self.assertIsNotNone(m)
availability_start_time = m.group(0)
print 'availabilityStartTime: ', availability_start_time
print availability_start_time
# Extract publishTime.
m = re.search('publishTime="[^"]+"', content)
self.assertIsNotNone(m)
publish_time = m.group(0)
print publish_time
with open(test_output, 'w') as f:
f.write(content.replace(availability_start_time, 'place_holder'))
f.write(content.replace(
availability_start_time,
'availabilityStartTime="place_holder"').replace(
publish_time, 'publishTime="some_publish_time"'))
self._DiffGold(test_output, golden_file_name)
def _AssertStreamInfo(self, stream, info):

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7679998874664307S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="audio">
<Representation id="0" bandwidth="69313" codecs="vorbis" mimeType="audio/webm" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7060000896453857S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="video" width="320" height="240" frameRate="1000000/33000" subsegmentAlignment="true" par="16:9">
<Representation id="0" bandwidth="210593" codecs="vp09.00.00.08.00.01.00.00" mimeType="video/mp4" sar="427:320">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7059998512268066S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="video" width="320" height="240" frameRate="1000000/33000" par="16:9">
<Representation id="0" bandwidth="205387" codecs="vp9" mimeType="video/webm" sar="427:320">
<BaseURL>output_video.webm</BaseURL>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.763174533843994S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<Representation id="0" bandwidth="885555" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.763174533843994S">
<Period>
<Period id="0">
<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 schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.763174533843994S">
<Period>
<Period id="0">
<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">
<BaseURL>output_video.mp4</BaseURL>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period start="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" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<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">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period start="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" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<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 schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period start="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" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
<Representation id="0" bandwidth="876470" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="00000000-0000-0000-0000-000000000000"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period start="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" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<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 schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period start="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" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="some_publish_time" availabilityStartTime="place_holder" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<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">
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.763174533843994S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="text">
<Representation id="0" bandwidth="256" mimeType="text/vtt">
<BaseURL>output_text.vtt</BaseURL>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7694332599639893S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<Representation id="0" bandwidth="265022" codecs="hev1.1.6.L63.80" mimeType="video/mp4" sar="1:1">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7360665798187256S">
<Period>
<Period id="0">
<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">
<BaseURL>output_0.mp4</BaseURL>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7060000896453857S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" subsegmentAlignment="true" par="16:9">
<Representation id="0" bandwidth="344796" codecs="vp08.00.00.08.01.01.00.00" mimeType="video/mp4" sar="1:1">
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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.7059998512268066S">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="1000000/33000" par="16:9">
<Representation id="0" bandwidth="338992" codecs="vp8" mimeType="video/webm" sar="1:1">
<BaseURL>output_video.webm</BaseURL>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/edash-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">
<Period>
<Period id="0">
<AdaptationSet id="0" contentType="text">
<Representation id="0" bandwidth="256" mimeType="text/vtt">
<BaseURL>output_text.vtt</BaseURL>

View File

@ -15,12 +15,14 @@
#include <string>
#include "packager/base/base64.h"
#include "packager/base/bind.h"
#include "packager/base/files/file_path.h"
#include "packager/base/logging.h"
#include "packager/base/memory/scoped_ptr.h"
#include "packager/base/strings/string_number_conversions.h"
#include "packager/base/strings/stringprintf.h"
#include "packager/base/synchronization/lock.h"
#include "packager/base/time/default_clock.h"
#include "packager/base/time/time.h"
#include "packager/media/file/file.h"
#include "packager/mpd/base/content_protection_element.h"
@ -121,8 +123,10 @@ bool Positive(double d) {
// Return current time in XML DateTime format. The value is in UTC, so the
// string ends with a 'Z'.
std::string XmlDateTimeNowWithOffset(int32_t offset_seconds) {
base::Time time = base::Time::Now();
std::string XmlDateTimeNowWithOffset(
int32_t offset_seconds,
base::Clock* clock) {
base::Time time = clock->Now();
time += base::TimeDelta::FromSeconds(offset_seconds);
base::Time::Exploded time_exploded;
time.UTCExplode(&time_exploded);
@ -397,7 +401,8 @@ class RepresentationStateChangeListenerImpl
MpdBuilder::MpdBuilder(MpdType type, const MpdOptions& mpd_options)
: type_(type),
mpd_options_(mpd_options),
adaptation_sets_deleter_(&adaptation_sets_) {}
adaptation_sets_deleter_(&adaptation_sets_),
clock_(new base::DefaultClock()) {}
MpdBuilder::~MpdBuilder() {}
@ -454,6 +459,11 @@ xmlDocPtr MpdBuilder::GenerateMpd() {
// Iterate thru AdaptationSets and add them to one big Period element.
XmlNode period("Period");
// Always set id=0 for now. Since this class can only generate one Period
// at the moment, just use a constant.
// Required for 'dynamic' MPDs.
period.SetId(0);
std::list<AdaptationSet*>::iterator adaptation_sets_it =
adaptation_sets_.begin();
for (; adaptation_sets_it != adaptation_sets_.end(); ++adaptation_sets_it) {
@ -539,6 +549,10 @@ void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
mpd_node->SetStringAttribute("type", kDynamicMpdType);
mpd_node->SetStringAttribute("profiles", kDynamicMpdProfile);
// No offset from NOW.
mpd_node->SetStringAttribute("publishTime",
XmlDateTimeNowWithOffset(0, clock_.get()));
// 'availabilityStartTime' is required for dynamic profile. Calculate if
// not already calculated.
if (availability_start_time_.empty()) {
@ -546,7 +560,8 @@ void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
if (GetEarliestTimestamp(&earliest_presentation_time)) {
availability_start_time_ =
XmlDateTimeNowWithOffset(mpd_options_.availability_time_offset -
std::ceil(earliest_presentation_time));
std::ceil(earliest_presentation_time),
clock_.get());
} else {
LOG(ERROR) << "Could not determine the earliest segment presentation "
"time for availabilityStartTime calculation.";

View File

@ -23,8 +23,11 @@
#include <string>
#include "packager/base/atomic_sequence_num.h"
#include "packager/base/callback.h"
#include "packager/base/gtest_prod_util.h"
#include "packager/base/stl_util.h"
#include "packager/base/time/clock.h"
#include "packager/base/time/time.h"
#include "packager/mpd/base/bandwidth_estimator.h"
#include "packager/mpd/base/content_protection_element.h"
#include "packager/mpd/base/media_info.pb.h"
@ -97,6 +100,12 @@ class MpdBuilder {
static void MakePathsRelativeToMpd(const std::string& mpd_path,
MediaInfo* media_info);
// Inject a |clock| that returns the current time.
/// This is for testing.
void InjectClockForTesting(scoped_ptr<base::Clock> clock) {
clock_ = clock.Pass();
}
private:
// DynamicMpdBuilderTest needs to set availabilityStartTime so that the test
// doesn't need to depend on current time.
@ -146,6 +155,10 @@ class MpdBuilder {
base::AtomicSequenceNumber adaptation_set_counter_;
base::AtomicSequenceNumber representation_counter_;
// By default, this returns the current time. This can be injected for
// testing.
scoped_ptr<base::Clock> clock_;
DISALLOW_COPY_AND_ASSIGN(MpdBuilder);
};

View File

@ -9,7 +9,6 @@
#include <inttypes.h>
#include <libxml/xmlstring.h>
#include "packager/base/strings/string_piece.h"
#include "packager/base/files/file_util.h"
#include "packager/base/logging.h"
#include "packager/base/strings/string_number_conversions.h"
@ -37,6 +36,16 @@ const char kSElementTemplateWithoutR[] =
"<S t=\"%" PRIu64 "\" d=\"%" PRIu64 "\"/>\n";
const int kDefaultStartNumber = 1;
class TestClock : public base::Clock {
public:
explicit TestClock(const base::Time& t) : time_(t) {}
~TestClock() override {}
base::Time Now() override { return time_; }
private:
base::Time time_;
};
// Get 'id' attribute from |node|, convert it to std::string and convert it to a
// number.
void ExpectXmlElementIdEqual(xmlNodePtr node, uint32_t id) {
@ -178,10 +187,26 @@ class DynamicMpdBuilderTest : public MpdBuilderTest<MpdBuilder::kDynamic> {
mpd_.availability_start_time_ = "2011-12-25T12:30:00";
// Override packager version string for testing.
mpd_.mpd_options_.packager_version_string = "<tag>-<hash>-<test>";
InjectTestClock();
}
MpdOptions* mutable_mpd_options() { return &mpd_.mpd_options_; }
// Injects a clock that always returns 2016 Jan 11 15:10:24 in UTC.
void InjectTestClock() {
base::Time::Exploded test_time = {.year = 2016,
.month = 1,
.day_of_week = 1, // Monday.
.day_of_month = 11,
.hour = 15,
.minute = 10,
.second = 24,
.millisecond = 0};
ASSERT_TRUE(test_time.HasValidValues());
mpd_.InjectClockForTesting(scoped_ptr<base::Clock>(
new TestClock(base::Time::FromUTCExploded(test_time))));
}
std::string GetDefaultMediaInfo() {
const char kMediaInfo[] =
"video_info {\n"
@ -253,12 +278,13 @@ class SegmentTemplateTest : public DynamicMpdBuilderTest {
const char kOutputTemplate[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\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\" "
"availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\">\n"
" <Period start=\"PT0S\">\n"
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
" xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
" availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
" type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
" publishTime=\"2016-01-11T15:10:24Z\">\n"
" <Period id=\"0\" start=\"PT0S\">\n"
" <AdaptationSet id=\"0\" width=\"720\" height=\"480\""
" frameRate=\"10/5\" contentType=\"video\""
" par=\"3:2\" segmentAlignment=\"true\">\n"
@ -342,8 +368,9 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
"xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" "
"availabilityStartTime=\"2011-12-25T12:30:00\" minBufferTime=\"PT2S\" "
"type=\"dynamic\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
"publishTime=\"2016-01-11T15:10:24Z\" "
"timeShiftBufferDepth=\"PT%dS\">\n"
" <Period start=\"PT0S\">\n"
" <Period id=\"0\" start=\"PT0S\">\n"
" <AdaptationSet id=\"0\" width=\"720\" height=\"480\""
" frameRate=\"10/2\" contentType=\"video\""
" par=\"3:2\" segmentAlignment=\"true\">\n"
@ -788,7 +815,7 @@ TEST_F(CommonMpdBuilderTest, AdaptationAddRoleElementMain) {
" minBufferTime=\"PT2S\" type=\"static\"\n"
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
" mediaPresentationDuration=\"PT0S\">\n"
" <Period>\n"
" <Period id=\"0\">\n"
" <AdaptationSet id=\"0\" contentType=\"\">\n"
" <Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"main\"/>\n"
" </AdaptationSet>\n"
@ -831,7 +858,7 @@ TEST_F(CommonMpdBuilderTest, CheckContentProtectionRoleRepresentationOrder) {
" minBufferTime=\"PT2S\" type=\"static\"\n"
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
" mediaPresentationDuration=\"PT0S\">\n"
" <Period>\n"
" <Period id=\"0\">\n"
" <AdaptationSet id=\"0\" contentType=\"audio\">\n"
" <ContentProtection schemeIdUri=\"any_scheme\"/>\n"
" <Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"main\"/>\n"
@ -1653,7 +1680,7 @@ TEST_F(CommonMpdBuilderTest, AdaptationSetAddContentProtectionAndUpdate) {
" minBufferTime=\"PT2S\" type=\"static\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" mediaPresentationDuration=\"PT0S\">"
" <Period>"
" <Period id=\"0\">"
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
" height=\"1080\" frameRate=\"3000/100\">"
" <ContentProtection"
@ -1682,7 +1709,7 @@ TEST_F(CommonMpdBuilderTest, AdaptationSetAddContentProtectionAndUpdate) {
" minBufferTime=\"PT2S\" type=\"static\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" mediaPresentationDuration=\"PT0S\">"
" <Period>"
" <Period id=\"0\">"
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
" height=\"1080\" frameRate=\"3000/100\">"
" <ContentProtection"
@ -1737,7 +1764,7 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
" minBufferTime=\"PT2S\" type=\"static\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" mediaPresentationDuration=\"PT0S\">"
" <Period>"
" <Period id=\"0\">"
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
" height=\"1080\" frameRate=\"3000/100\">"
" <ContentProtection"
@ -1766,7 +1793,7 @@ TEST_F(CommonMpdBuilderTest, UpdateToRemovePsshElement) {
" minBufferTime=\"PT2S\" type=\"static\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" mediaPresentationDuration=\"PT0S\">"
" <Period>"
" <Period id=\"0\">"
" <AdaptationSet id=\"0\" contentType=\"video\" width=\"1920\""
" height=\"1080\" frameRate=\"3000/100\">"
" <ContentProtection"
@ -1863,7 +1890,7 @@ TEST_F(StaticMpdBuilderTest, AudioChannelConfigurationWithContentProtection) {
" minBufferTime=\"PT2S\" type=\"static\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" mediaPresentationDuration=\"PT24.00943374633789S\">"
" <Period>"
" <Period id=\"0\">"
" <AdaptationSet id=\"0\" contentType=\"audio\">"
" <Representation id=\"0\" bandwidth=\"195857\" codecs=\"mp4a.40.2\""
" mimeType=\"audio/mp4\" audioSamplingRate=\"44100\">"
@ -1963,7 +1990,7 @@ TEST_F(StaticMpdBuilderTest, Text) {
" minBufferTime=\"PT2S\" type=\"static\""
" profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\""
" mediaPresentationDuration=\"PT35S\">"
" <Period>"
" <Period id=\"0\">"
" <AdaptationSet id=\"0\" contentType=\"text\" lang=\"en\">"
" <Role schemeIdUri=\"urn:mpeg:dash:role:2011\""
" value=\"subtitle\"/>\n"
@ -2005,8 +2032,9 @@ TEST_F(DynamicMpdBuilderTest, CheckMpdAttributes) {
"minBufferTime=\"PT2S\" "
"type=\"dynamic\" "
"profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" "
"publishTime=\"2016-01-11T15:10:24Z\" "
"availabilityStartTime=\"2011-12-25T12:30:00\">\n"
" <Period start=\"PT0S\"/>\n"
" <Period id=\"0\" start=\"PT0S\"/>\n"
"</MPD>\n";
std::string mpd_doc;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
<Period>
<Period id="0">
<AdaptationSet id="0" width="720" height="480" frameRate="10/1" contentType="video" par="3:2">
<Representation id="1" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" sar="1:1">
<BaseURL>test_output_file_name1.mp4</BaseURL>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" availabilityStartTime="2011-12-25T12:30:00" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011">
<Period start="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" availabilityStartTime="2011-12-25T12:30:00" minBufferTime="PT2S" type="dynamic" profiles="urn:mpeg:dash:profile:isoff-live:2011" publishTime="2016-01-11T15:10:24Z">
<Period id="0" start="PT0S">
<AdaptationSet id="0" width="720" height="480" frameRate="10/5" contentType="video" par="3:2" segmentAlignment="true">
<Representation id="0" bandwidth="102400" codecs="avc1.010101" mimeType="video/mp4" sar="1:1">
<SegmentTemplate timescale="1000" initialization="init.mp4" media="$Time$.mp4">

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
<Period>
<Period id="0">
<AdaptationSet id="0" width="720" height="480" frameRate="10/1" contentType="video" par="3:2">
<Representation id="0" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" sar="1:1">
<BaseURL>test_output_file_name1.mp4</BaseURL>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" minBufferTime="PT2S" type="static" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" mediaPresentationDuration="PT10.5S">
<Period>
<Period id="0">
<AdaptationSet id="0" maxWidth="720" maxHeight="480" maxFrameRate="10/1" contentType="video">
<Representation id="0" bandwidth="7620" codecs="avc1.010101" mimeType="video/mp4" width="720" height="480" frameRate="10/1" sar="1:1">
<BaseURL>test_output_file_name1.mp4</BaseURL>