Skip to content

Commit

Permalink
Adding support for adding Session Based Descriptor Document Essential…
Browse files Browse the repository at this point in the history
… Property.
  • Loading branch information
sr1990 committed Oct 16, 2020
1 parent 2909ca0 commit cd00c09
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 5 deletions.
20 changes: 20 additions & 0 deletions packager/app/mpd_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,23 @@ DEFINE_bool(include_mspr_pro_for_playready,
"If enabled, PlayReady Object <mspr:pro> will be inserted into "
"<ContentProtection ...> element alongside with <cenc:pssh> "
"when using PlayReady protection system.");


DEFINE_string(sbd_url_all, "", "Comma separated URLs of sbd document.Add to all adaptation sets.");
DEFINE_string(sbd_template_all, "", "Comma separated template used to create URL query.");
DEFINE_string(sbd_key_all, "", "Comma separated SBD keys to fetch from sbd client.");


DEFINE_string(sbd_url_video, "", "Comma separated URL of sbd document. Add to all video adaptation sets");
DEFINE_string(sbd_template_video, "", "Comma separated template used to create URL query.");
DEFINE_string(sbd_key_video, "", "SBD keys to fetch from sbd client.");


DEFINE_string(sbd_url_audio, "", "Comma separated URL of sbd document.Add to all adaptation sets.");
DEFINE_string(sbd_template_audio, "", "Comma separated Template used to create URL query.");
DEFINE_string(sbd_key_audio, "", "Comma separated SBD keys to fetch from sbd client.");


DEFINE_string(sbd_url_text, "", "Comma separated URL of sbd document. Add to all text adapatation sets.");
DEFINE_string(sbd_template_text, "", "Comma separated Template used to create URL query.");
DEFINE_string(sbd_key_text, "", "Comma separated SBD key-value pairs.");
16 changes: 16 additions & 0 deletions packager/app/mpd_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,21 @@ DECLARE_bool(generate_dash_if_iop_compliant_mpd);
DECLARE_bool(allow_approximate_segment_timeline);
DECLARE_bool(allow_codec_switching);
DECLARE_bool(include_mspr_pro_for_playready);
//Session based urls
DECLARE_string(sbd_url_all);
DECLARE_string(sbd_template_all);
DECLARE_string(sbd_key_all);

DECLARE_string(sbd_url_video);
DECLARE_string(sbd_template_video);
DECLARE_string(sbd_key_video);

DECLARE_string(sbd_url_audio);
DECLARE_string(sbd_template_audio);
DECLARE_string(sbd_key_audio);

DECLARE_string(sbd_url_text);
DECLARE_string(sbd_template_text);
DECLARE_string(sbd_key_text);

#endif // APP_MPD_FLAGS_H_
61 changes: 61 additions & 0 deletions packager/app/packager_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,53 @@ bool ParseProtectionSystems(const std::string& protection_systems_str,
return true;
}

// Add SBD params
void addSBDParams(std::string& FLAGS_sbd_url, std::string& FLAGS_sbd_template,
std::string& FLAGS_sbd_key, std::string content_type,
MpdParams& mpd_params) {
//Get comma separted urls
std::vector<std::string> sbd_urls;
base::SplitStringUsingSubstr(FLAGS_sbd_url, ",", &sbd_urls);

std::vector<std::string> sbd_templates;
base::SplitStringUsingSubstr(FLAGS_sbd_template, ",", &sbd_templates);

std::vector<std::vector<std::pair<std::string,std::string>>> sbd_keys_all;
if (!FLAGS_sbd_key.empty()) {
std::vector<std::string> sbd_keys;

base::SplitStringUsingSubstr(FLAGS_sbd_key, ":", &sbd_keys);
for (auto sbd_key: sbd_keys) {
base::StringPairs pairs;
if (!base::SplitStringIntoKeyValuePairs(sbd_key, '=', ',',
&pairs)) {
LOG(ERROR) << "Invalid --sbd_key keyname/defaultvalue pairs.";

}

std::vector<std::pair<std::string,std::string>> v;
for (const auto& string_pair : pairs) {
v.push_back(std::make_pair(string_pair.first,string_pair.second));
}
sbd_keys_all.push_back(v);
}
}

//store sbd details in mpd params.
for (int i=0;i<(int)sbd_urls.size();i++) {
if (content_type == "all")
mpd_params.sbd_adaptation_set_all.push_back({sbd_urls[i], sbd_templates[i], sbd_keys_all[i]});
if (content_type == "video")
mpd_params.sbd_adaptation_set_video.push_back({sbd_urls[i], sbd_templates[i], sbd_keys_all[i]});
if (content_type == "audio")
mpd_params.sbd_adaptation_set_audio.push_back({sbd_urls[i], sbd_templates[i], sbd_keys_all[i]});
if (content_type == "text")
mpd_params.sbd_adaptation_set_text.push_back({sbd_urls[i], sbd_templates[i], sbd_keys_all[i]});
}

}


base::Optional<PackagingParams> GetPackagingParams() {
PackagingParams packaging_params;

Expand Down Expand Up @@ -476,6 +523,20 @@ base::Optional<PackagingParams> GetPackagingParams() {
mpd_params.allow_codec_switching = FLAGS_allow_codec_switching;
mpd_params.include_mspr_pro = FLAGS_include_mspr_pro_for_playready;

if (!FLAGS_sbd_url_all.empty())
addSBDParams(FLAGS_sbd_url_all, FLAGS_sbd_template_all, FLAGS_sbd_key_all,
"all", mpd_params);

if (!FLAGS_sbd_url_video.empty())
addSBDParams(FLAGS_sbd_url_video, FLAGS_sbd_template_video, FLAGS_sbd_key_video,
"video", mpd_params);
if (!FLAGS_sbd_url_audio.empty())
addSBDParams(FLAGS_sbd_url_audio, FLAGS_sbd_template_audio, FLAGS_sbd_key_audio,
"audio", mpd_params);
if (!FLAGS_sbd_url_text.empty())
addSBDParams(FLAGS_sbd_url_text, FLAGS_sbd_template_text, FLAGS_sbd_key_text,
"text", mpd_params);

HlsParams& hls_params = packaging_params.hls_params;
if (!GetHlsPlaylistType(FLAGS_hls_playlist_type, &hls_params.playlist_type)) {
return base::nullopt;
Expand Down
63 changes: 62 additions & 1 deletion packager/app/test/packager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,19 @@ def _GetFlags(self,
default_language=None,
segment_duration=1.0,
use_fake_clock=True,
allow_codec_switching=False):
allow_codec_switching=False,
sbd_url_all=None,
sbd_template_all=None,
sbd_key_all=None,
sbd_url_video=None,
sbd_template_video=None,
sbd_key_video=None,
sbd_url_audio=None,
sbd_template_audio=None,
sbd_key_audio=None,
sbd_url_text=None,
sbd_template_text=None,
sbd_key_text=None):
flags = []

if not strip_parameter_set_nalus:
Expand Down Expand Up @@ -554,6 +566,34 @@ def _GetFlags(self,
if utc_timings:
flags += ['--utc_timings', utc_timings]

if sbd_url_all:
flags += ['--sbd_url_all', sbd_url_all]
if sbd_template_all:
flags += ['--sbd_template_all', sbd_template_all]
if sbd_key_all:
flags += ['--sbd_key_all', sbd_key_all]

if sbd_url_video:
flags += ['--sbd_url_video', sbd_url_video]
if sbd_template_video:
flags += ['--sbd_template_video', sbd_template_video]
if sbd_key_video:
flags += ['--sbd_key_video', sbd_key_video]

if sbd_url_audio:
flags += ['--sbd_url_audio', sbd_url_audio]
if sbd_template_audio:
flags += ['--sbd_template_audio', sbd_template_audio]
if sbd_key_audio:
flags += ['--sbd_key_audio', sbd_key_audio]

if sbd_url_text:
flags += ['--sbd_url_text', sbd_url_text]
if sbd_template_text:
flags += ['--sbd_template_text', sbd_template_text]
if sbd_key_text:
flags += ['--sbd_key_text', sbd_key_text]

if generate_static_live_mpd:
flags += ['--generate_static_live_mpd']

Expand Down Expand Up @@ -786,6 +826,27 @@ def testDashOnlyAndHlsOnly(self):
self._GetFlags(output_dash=True, output_hls=True))
self._CheckTestResults('hls-only-dash-only')

def testSBD(self):
streams = [
self._GetStream('video'),
self._GetStream('audio'),
]
self.assertPackageSuccess(
streams,
self._GetFlags(output_dash=True,
sbd_url_all='all_adaptation_sets',
sbd_template_all='t1',
sbd_key_all='k1=v1,k2=v2',
sbd_url_video='video1,video2',
sbd_template_video='t2,t3',
sbd_key_video='k3=v3:k4=v4' ,
sbd_url_audio='audio1,audio2' ,
sbd_template_audio='t4,t5',
sbd_key_audio='k5=v5:k6=v6'))


self._CheckTestResults('sbd_test')

def testAudioVideoWithLanguageOverride(self):
self.assertPackageSuccess(
self._GetStreams(['audio', 'video'], language='por', hls=True),
Expand Down
Binary file not shown.
Binary file not shown.
43 changes: 43 additions & 0 deletions packager/app/test/testdata/sbd_test/output.mpd
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--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" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:sbd="urn:mpeg:dash:sbd:2020" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.7360665798187256S">
<Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<EssentialProperty schemeIdUri="urn:mpeg:dash:sbd:2020" value="video1" sbd:template="t2">
<sbd:Key name="k3" defaultValue="v3"/>
</EssentialProperty>
<EssentialProperty schemeIdUri="urn:mpeg:dash:sbd:2020" value="video2" sbd:template="t3">
<sbd:Key name="k4" defaultValue="v4"/>
</EssentialProperty>
<EssentialProperty schemeIdUri="urn:mpeg:dash:sbd:2020" value="all_adaptation_sets" sbd:template="t1">
<sbd:Key name="k1" defaultValue="v1"/>
<sbd:Key name="k2" defaultValue="v2"/>
</EssentialProperty>
<Representation id="0" bandwidth="973483" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-video.mp4</BaseURL>
<SegmentBase indexRange="863-930" timescale="30000">
<Initialization range="0-862"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" subsegmentAlignment="true">
<EssentialProperty schemeIdUri="urn:mpeg:dash:sbd:2020" value="audio1" sbd:template="t4">
<sbd:Key name="k5" defaultValue="v5"/>
</EssentialProperty>
<EssentialProperty schemeIdUri="urn:mpeg:dash:sbd:2020" value="audio2" sbd:template="t5">
<sbd:Key name="k6" defaultValue="v6"/>
</EssentialProperty>
<EssentialProperty schemeIdUri="urn:mpeg:dash:sbd:2020" value="all_adaptation_sets" sbd:template="t1">
<sbd:Key name="k1" defaultValue="v1"/>
<sbd:Key name="k2" defaultValue="v2"/>
</EssentialProperty>
<Representation id="1" bandwidth="133334" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>bear-640x360-audio.mp4</BaseURL>
<SegmentBase indexRange="797-864" timescale="44100">
<Initialization range="0-796"/>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>
</MPD>
38 changes: 37 additions & 1 deletion packager/mpd/base/adaptation_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,45 @@ xml::scoped_xml_ptr<xmlNode> AdaptationSet::GetXml() {
}
if (!trick_play_reference_ids.empty()) {
adaptation_set.AddEssentialProperty(
"http://dashif.org/guidelines/trickmode", trick_play_reference_ids);
"http://dashif.org/guidelines/trickmode",
trick_play_reference_ids,
mpd_options_);
}

//Add sbd essential property here
// video
if (!mpd_options_.mpd_params.sbd_adaptation_set_video.empty() &&
content_type_ == "video") {

adaptation_set.AddEssentialProperty("urn:mpeg:dash:sbd:2020",
"video",
mpd_options_);
}
//audio
if (!mpd_options_.mpd_params.sbd_adaptation_set_audio.empty() &&
content_type_ == "audio") {

adaptation_set.AddEssentialProperty("urn:mpeg:dash:sbd:2020",
"audio",
mpd_options_);
}
//text
if (!mpd_options_.mpd_params.sbd_adaptation_set_text.empty() &&
content_type_ == "text") {

adaptation_set.AddEssentialProperty("urn:mpeg:dash:sbd:2020",
"text",
mpd_options_);
}
//all
if (!mpd_options_.mpd_params.sbd_adaptation_set_all.empty()) {

adaptation_set.AddEssentialProperty("urn:mpeg:dash:sbd:2020",
"all",
mpd_options_);
}


std::string switching_ids;
for (const AdaptationSet* adaptation_set : switchable_adaptation_sets_) {
if (!switching_ids.empty())
Expand Down
2 changes: 2 additions & 0 deletions packager/mpd/base/mpd_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ void AddMpdNameSpaceInfo(XmlNode* mpd) {
"urn:marlin:mas:1-0:services:schemas:mpd";
static const char kXmlNamespaceXlink[] = "http://www.w3.org/1999/xlink";
static const char kMsprNamespace[] = "urn:microsoft:playready";
static const char kSbdNamespace[] = "urn:mpeg:dash:sbd:2020";

const std::map<std::string, std::string> uris = {
{"cenc", kCencNamespace},
{"mas", kMarlinNamespace},
{"xlink", kXmlNamespaceXlink},
{"mspr", kMsprNamespace},
{"sbd", kSbdNamespace},
};

for (const std::string& namespace_name : namespaces) {
Expand Down
71 changes: 69 additions & 2 deletions packager/mpd/base/xml/xml_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,78 @@ void RepresentationBaseXmlNode::AddSupplementalProperty(
const std::string& value) {
AddDescriptor("SupplementalProperty", scheme_id_uri, value);
}

bool RepresentationBaseXmlNode::AddSBDInfo(
const std::vector<MpdParams::SBD>& sbd_adaptation_set,
const std::string& descriptor_name,
const std::string& scheme_id_uri,
const std::string& value) {

for (const auto& sbd: sbd_adaptation_set) {

XmlNode descriptor(descriptor_name.c_str());
descriptor.SetStringAttribute("schemeIdUri", scheme_id_uri);

if (!sbd.url_.empty())
descriptor.SetStringAttribute("value", sbd.url_);

if (!sbd.template_.empty())
descriptor.SetStringAttribute("sbd:template", sbd.template_);

if (!sbd.sbd_keys_.empty()) {
for (auto key: sbd.sbd_keys_) {
XmlNode st("sbd:Key");
st.SetStringAttribute("name", key.first);
if (key.second.empty()) {
st.SetStringAttribute("defaultValue", "nil");
} else {
st.SetStringAttribute("defaultValue", key.second);
}
descriptor.AddChild(st.PassScopedPtr());
}
}

if (!AddChild(descriptor.PassScopedPtr()))
return false;
}
return true;

}

bool RepresentationBaseXmlNode::AddDescriptorSBD(
const std::string& descriptor_name,
const std::string& scheme_id_uri,
const std::string& value,
const MpdOptions& mpd_options) {
//Check for Video/Audio/Text/All
if (value == "all")
return AddSBDInfo(mpd_options.mpd_params.sbd_adaptation_set_all,
descriptor_name, scheme_id_uri, value);
else if (value == "video")
return AddSBDInfo(mpd_options.mpd_params.sbd_adaptation_set_video,
descriptor_name, scheme_id_uri, value);
else if (value == "audio")
return AddSBDInfo(mpd_options.mpd_params.sbd_adaptation_set_audio,
descriptor_name, scheme_id_uri, value);
else if (value == "text")
return AddSBDInfo(mpd_options.mpd_params.sbd_adaptation_set_text,
descriptor_name, scheme_id_uri, value);

return true;
}

void RepresentationBaseXmlNode::AddEssentialProperty(
const std::string& scheme_id_uri,
const std::string& value) {
AddDescriptor("EssentialProperty", scheme_id_uri, value);
const std::string& value,
const MpdOptions& mpd_options) {

if (scheme_id_uri == "urn:mpeg:dash:sbd:2020") {
AddDescriptorSBD("EssentialProperty",
scheme_id_uri,
value, mpd_options);
} else {
AddDescriptor("EssentialProperty", scheme_id_uri, value);
}
}

bool RepresentationBaseXmlNode::AddDescriptor(
Expand Down
Loading

0 comments on commit cd00c09

Please sign in to comment.