shaka-packager/docs/db/dfb/mpd__utils_8cc_source.html

86 lines
68 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Shaka Packager SDK: packager/mpd/base/mpd_utils.cc Source File</title>
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Shaka Packager SDK
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('../../',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="../../dir_3f8eec2fc361645de4b1ec14c19fffc7.html">packager</a></li><li class="navelem"><a class="el" href="../../dir_b885194e7131202a9b4650a8967e838c.html">mpd</a></li><li class="navelem"><a class="el" href="../../dir_6fe4b0529cd3ec97045d3314254a0cce.html">base</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">mpd_utils.cc</div> </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;<span class="comment">// Copyright 2014 Google Inc. All rights reserved.</span></div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160;<span class="comment">// Use of this source code is governed by a BSD-style</span></div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160;<span class="comment">// license that can be found in the LICENSE file or at</span></div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160;<span class="comment">// https://developers.google.com/open-source/licenses/bsd</span></div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160;<span class="preprocessor">#include &quot;packager/mpd/base/mpd_utils.h&quot;</span></div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span>&#160;<span class="preprocessor">#include &lt;gflags/gflags.h&gt;</span></div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160;<span class="preprocessor">#include &lt;libxml/tree.h&gt;</span></div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span>&#160;</div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span>&#160;<span class="preprocessor">#include &quot;packager/base/base64.h&quot;</span></div><div class="line"><a name="l00013"></a><span class="lineno"> 13</span>&#160;<span class="preprocessor">#include &quot;packager/base/logging.h&quot;</span></div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160;<span class="preprocessor">#include &quot;packager/base/strings/string_number_conversions.h&quot;</span></div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160;<span class="preprocessor">#include &quot;packager/base/strings/string_util.h&quot;</span></div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/language_utils.h&quot;</span></div><div class="line"><a name="l00017"></a><span class="lineno"> 17</span>&#160;<span class="preprocessor">#include &quot;packager/mpd/base/adaptation_set.h&quot;</span></div><div class="line"><a name="l00018"></a><span class="lineno"> 18</span>&#160;<span class="preprocessor">#include &quot;packager/mpd/base/content_protection_element.h&quot;</span></div><div class="line"><a name="l00019"></a><span class="lineno"> 19</span>&#160;<span class="preprocessor">#include &quot;packager/mpd/base/representation.h&quot;</span></div><div class="line"><a name="l00020"></a><span class="lineno"> 20</span>&#160;<span class="preprocessor">#include &quot;packager/mpd/base/xml/scoped_xml_ptr.h&quot;</span></div><div class="line"><a name="l00021"></a><span class="lineno"> 21</span>&#160;</div><div class="line"><a name="l00022"></a><span class="lineno"> 22</span>&#160;DEFINE_bool(</div><div class="line"><a name="l00023"></a><span class="lineno"> 23</span>&#160; use_legacy_vp9_codec_string,</div><div class="line"><a name="l00024"></a><span class="lineno"> 24</span>&#160; <span class="keyword">false</span>,</div><div class="line"><a name="l00025"></a><span class="lineno"> 25</span>&#160; <span class="stringliteral">&quot;Use legacy vp9 codec string &#39;vp9&#39; if set to true; otherwise new style &quot;</span></div><div class="line"><a name="l00026"></a><span class="lineno"> 26</span>&#160; <span class="stringliteral">&quot;vp09.xx.xx.xx... codec string will be used. Default to false as indicated &quot;</span></div><div class="line"><a name="l00027"></a><span class="lineno"> 27</span>&#160; <span class="stringliteral">&quot;in https://github.com/google/shaka-packager/issues/406, all major &quot;</span></div><div class="line"><a name="l00028"></a><span class="lineno"> 28</span>&#160; <span class="stringliteral">&quot;browsers and platforms already support the new &#39;vp09&#39; codec string.&quot;</span>);</div><div class="line"><a name="l00029"></a><span class="lineno"> 29</span>&#160;</div><div class="line"><a name="l00030"></a><span class="lineno"> 30</span>&#160;<span class="keyword">namespace </span><a class="code" href="../../d8/daf/namespaceshaka.html">shaka</a> {</div><div class="line"><a name="l00031"></a><span class="lineno"> 31</span>&#160;<span class="keyword">namespace </span>{</div><div class="line"><a name="l00032"></a><span class="lineno"> 32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno"> 33</span>&#160;<span class="keywordtype">bool</span> IsKeyRotationDefaultKeyId(<span class="keyword">const</span> std::string&amp; key_id) {</div><div class="line"><a name="l00034"></a><span class="lineno"> 34</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">char</span> c : key_id) {</div><div class="line"><a name="l00035"></a><span class="lineno"> 35</span>&#160; <span class="keywordflow">if</span> (c != <span class="charliteral">&#39;\0&#39;</span>)</div><div class="line"><a name="l00036"></a><span class="lineno"> 36</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l00037"></a><span class="lineno"> 37</span>&#160; }</div><div class="line"><a name="l00038"></a><span class="lineno"> 38</span>&#160; <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l00039"></a><span class="lineno"> 39</span>&#160;}</div><div class="line"><a name="l00040"></a><span class="lineno"> 40</span>&#160;</div><div class="line"><a name="l00041"></a><span class="lineno"> 41</span>&#160;std::string TextCodecString(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00042"></a><span class="lineno"> 42</span>&#160; CHECK(media_info.has_text_info());</div><div class="line"><a name="l00043"></a><span class="lineno"> 43</span>&#160; <span class="keyword">const</span> <span class="keyword">auto</span> container_type = media_info.container_type();</div><div class="line"><a name="l00044"></a><span class="lineno"> 44</span>&#160;</div><div class="line"><a name="l00045"></a><span class="lineno"> 45</span>&#160; <span class="comment">// Codecs are not needed when mimeType is &quot;text/*&quot;. Having a codec would be</span></div><div class="line"><a name="l00046"></a><span class="lineno"> 46</span>&#160; <span class="comment">// redundant.</span></div><div class="line"><a name="l00047"></a><span class="lineno"> 47</span>&#160; <span class="keywordflow">if</span> (container_type == MediaInfo::CONTAINER_TEXT) {</div><div class="line"><a name="l00048"></a><span class="lineno"> 48</span>&#160; <span class="keywordflow">return</span> <span class="stringliteral">&quot;&quot;</span>;</div><div class="line"><a name="l00049"></a><span class="lineno"> 49</span>&#160; }</div><div class="line"><a name="l00050"></a><span class="lineno"> 50</span>&#160;</div><div class="line"><a name="l00051"></a><span class="lineno"> 51</span>&#160; <span class="comment">// DASH IOP mentions that the codec for ttml in mp4 is stpp, so override</span></div><div class="line"><a name="l00052"></a><span class="lineno"> 52</span>&#160; <span class="comment">// the default codec value.</span></div><div class="line"><a name="l00053"></a><span class="lineno"> 53</span>&#160; <span class="keyword">const</span> std::string&amp; codec = media_info.text_info().codec();</div><div class="line"><a name="l00054"></a><span class="lineno"> 54</span>&#160; <span class="keywordflow">if</span> (codec == <span class="stringliteral">&quot;ttml&quot;</span> &amp;&amp; container_type == MediaInfo::CONTAINER_MP4) {</div><div class="line"><a name="l00055"></a><span class="lineno"> 55</span>&#160; <span class="keywordflow">return</span> <span class="stringliteral">&quot;stpp&quot;</span>;</div><div class="line"><a name="l00056"></a><span class="lineno"> 56</span>&#160; }</div><div class="line"><a name="l00057"></a><span class="lineno"> 57</span>&#160;</div><div class="line"><a name="l00058"></a><span class="lineno"> 58</span>&#160; <span class="keywordflow">return</span> codec;</div><div class="line"><a name="l00059"></a><span class="lineno"> 59</span>&#160;}</div><div class="line"><a name="l00060"></a><span class="lineno"> 60</span>&#160;</div><div class="line"><a name="l00061"></a><span class="lineno"> 61</span>&#160;} <span class="comment">// namespace</span></div><div class="line"><a name="l00062"></a><span class="lineno"> 62</span>&#160;</div><div class="line"><a name="l00063"></a><span class="lineno"> 63</span>&#160;<span class="keywordtype">bool</span> HasVODOnlyFields(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00064"></a><span class="lineno"> 64</span>&#160; <span class="keywordflow">return</span> media_info.has_init_range() || media_info.has_index_range() ||</div><div class="line"><a name="l00065"></a><span class="lineno"> 65</span>&#160; media_info.has_media_file_url();</div><div class="line"><a name="l00066"></a><span class="lineno"> 66</span>&#160;}</div><div class="line"><a name="l00067"></a><span class="lineno"> 67</span>&#160;</div><div class="line"><a name="l00068"></a><span class="lineno"> 68</span>&#160;<span class="keywordtype">bool</span> HasLiveOnlyFields(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00069"></a><span class="lineno"> 69</span>&#160; <span class="keywordflow">return</span> media_info.has_init_segment_url() ||</div><div class="line"><a name="l00070"></a><span class="lineno"> 70</span>&#160; media_info.has_segment_template_url();</div><div class="line"><a name="l00071"></a><span class="lineno"> 71</span>&#160;}</div><div class="line"><a name="l00072"></a><span class="lineno"> 72</span>&#160;</div><div class="line"><a name="l00073"></a><span class="lineno"> 73</span>&#160;<span class="keywordtype">void</span> RemoveDuplicateAttributes(</div><div class="line"><a name="l00074"></a><span class="lineno"> 74</span>&#160; ContentProtectionElement* content_protection_element) {</div><div class="line"><a name="l00075"></a><span class="lineno"> 75</span>&#160; DCHECK(content_protection_element);</div><div class="line"><a name="l00076"></a><span class="lineno"> 76</span>&#160; <span class="keyword">typedef</span> std::map&lt;std::string, std::string&gt; AttributesMap;</div><div class="line"><a name="l00077"></a><span class="lineno"> 77</span>&#160;</div><div class="line"><a name="l00078"></a><span class="lineno"> 78</span>&#160; AttributesMap&amp; attributes = content_protection_element-&gt;additional_attributes;</div><div class="line"><a name="l00079"></a><span class="lineno"> 79</span>&#160; <span class="keywordflow">if</span> (!content_protection_element-&gt;value.empty())</div><div class="line"><a name="l00080"></a><span class="lineno"> 80</span>&#160; attributes.erase(<span class="stringliteral">&quot;value&quot;</span>);</div><div class="line"><a name="l00081"></a><span class="lineno"> 81</span>&#160;</div><div class="line"><a name="l00082"></a><span class="lineno"> 82</span>&#160; <span class="keywordflow">if</span> (!content_protection_element-&gt;scheme_id_uri.empty())</div><div class="line"><a name="l00083"></a><span class="lineno"> 83</span>&#160; attributes.erase(<span class="stringliteral">&quot;schemeIdUri&quot;</span>);</div><div class="line"><a name="l00084"></a><span class="lineno"> 84</span>&#160;}</div><div class="line"><a name="l00085"></a><span class="lineno"> 85</span>&#160;</div><div class="line"><a name="l00086"></a><span class="lineno"> 86</span>&#160;std::string GetLanguage(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00087"></a><span class="lineno"> 87</span>&#160; std::string lang;</div><div class="line"><a name="l00088"></a><span class="lineno"> 88</span>&#160; <span class="keywordflow">if</span> (media_info.has_audio_info()) {</div><div class="line"><a name="l00089"></a><span class="lineno"> 89</span>&#160; lang = media_info.audio_info().language();</div><div class="line"><a name="l00090"></a><span class="lineno"> 90</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (media_info.has_text_info()) {</div><div class="line"><a name="l00091"></a><span class="lineno"> 91</span>&#160; lang = media_info.text_info().language();</div><div class="line"><a name="l00092"></a><span class="lineno"> 92</span>&#160; }</div><div class="line"><a name="l00093"></a><span class="lineno"> 93</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../d8/daf/namespaceshaka.html#a5f657931280fdf63cae2ed8a8f891288">LanguageToShortestForm</a>(lang);</div><div class="line"><a name="l00094"></a><span class="lineno"> 94</span>&#160;}</div><div class="line"><a name="l00095"></a><span class="lineno"> 95</span>&#160;</div><div class="line"><a name="l00096"></a><span class="lineno"> 96</span>&#160;std::string GetCodecs(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00097"></a><span class="lineno"> 97</span>&#160; CHECK(OnlyOneTrue(media_info.has_video_info(), media_info.has_audio_info(),</div><div class="line"><a name="l00098"></a><span class="lineno"> 98</span>&#160; media_info.has_text_info()));</div><div class="line"><a name="l00099"></a><span class="lineno"> 99</span>&#160;</div><div class="line"><a name="l00100"></a><span class="lineno"> 100</span>&#160; <span class="keywordflow">if</span> (media_info.has_video_info()) {</div><div class="line"><a name="l00101"></a><span class="lineno"> 101</span>&#160; <span class="keywordflow">if</span> (media_info.container_type() == MediaInfo::CONTAINER_WEBM) {</div><div class="line"><a name="l00102"></a><span class="lineno"> 102</span>&#160; std::string codec = media_info.video_info().codec().substr(0, 4);</div><div class="line"><a name="l00103"></a><span class="lineno"> 103</span>&#160; <span class="comment">// media_info.video_info().codec() contains new revised codec string</span></div><div class="line"><a name="l00104"></a><span class="lineno"> 104</span>&#160; <span class="comment">// specified by &quot;VPx in ISO BMFF&quot; document, which is not compatible to</span></div><div class="line"><a name="l00105"></a><span class="lineno"> 105</span>&#160; <span class="comment">// old codec strings in WebM. Hack it here before all browsers support</span></div><div class="line"><a name="l00106"></a><span class="lineno"> 106</span>&#160; <span class="comment">// new codec strings.</span></div><div class="line"><a name="l00107"></a><span class="lineno"> 107</span>&#160; <span class="keywordflow">if</span> (codec == <span class="stringliteral">&quot;vp08&quot;</span>)</div><div class="line"><a name="l00108"></a><span class="lineno"> 108</span>&#160; <span class="keywordflow">return</span> <span class="stringliteral">&quot;vp8&quot;</span>;</div><div class="line"><a name="l00109"></a><span class="lineno"> 109</span>&#160; <span class="keywordflow">if</span> (FLAGS_use_legacy_vp9_codec_string) {</div><div class="line"><a name="l00110"></a><span class="lineno"> 110</span>&#160; <span class="keywordflow">if</span> (codec == <span class="stringliteral">&quot;vp09&quot;</span>)</div><div class="line"><a name="l00111"></a><span class="lineno"> 111</span>&#160; <span class="keywordflow">return</span> <span class="stringliteral">&quot;vp9&quot;</span>;</div><div class="line"><a name="l00112"></a><span class="lineno"> 112</span>&#160; }</div><div class="line"><a name="l00113"></a><span class="lineno"> 113</span>&#160; }</div><div class="line"><a name="l00114"></a><span class="lineno"> 114</span>&#160; <span class="keywordflow">return</span> media_info.video_info().codec();</div><div class="line"><a name="l00115"></a><span class="lineno"> 115</span>&#160; }</div><div class="line"><a name="l00116"></a><span class="lineno"> 116</span>&#160;</div><div class="line"><a name="l00117"></a><span class="lineno"> 117</span>&#160; <span class="keywordflow">if</span> (media_info.has_audio_info())</div><div class="line"><a name="l00118"></a><span class="lineno"> 118</span>&#160; <span class="keywordflow">return</span> media_info.audio_info().codec();</div><div class="line"><a name="l00119"></a><span class="lineno"> 119</span>&#160;</div><div class="line"><a name="l00120"></a><span class="lineno"> 120</span>&#160; <span class="keywordflow">if</span> (media_info.has_text_info())</div><div class="line"><a name="l00121"></a><span class="lineno"> 121</span>&#160; <span class="keywordflow">return</span> TextCodecString(media_info);</div><div class="line"><a name="l00122"></a><span class="lineno"> 122</span>&#160;</div><div class="line"><a name="l00123"></a><span class="lineno"> 123</span>&#160; NOTREACHED();</div><div class="line"><a name="l00124"></a><span class="lineno"> 124</span>&#160; <span class="keywordflow">return</span> <span class="stringliteral">&quot;&quot;</span>;</div><div class="line"><a name="l00125"></a><span class="lineno"> 125</span>&#160;}</div><div class="line"><a name="l00126"></a><span class="lineno"> 126</span>&#160;</div><div class="line"><a name="l00127"></a><span class="lineno"> 127</span>&#160;std::string GetBaseCodec(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00128"></a><span class="lineno"> 128</span>&#160; std::string codec;</div><div class="line"><a name="l00129"></a><span class="lineno"> 129</span>&#160; <span class="keywordflow">if</span> (media_info.has_video_info()) {</div><div class="line"><a name="l00130"></a><span class="lineno"> 130</span>&#160; codec = media_info.video_info().codec();</div><div class="line"><a name="l00131"></a><span class="lineno"> 131</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (media_info.has_audio_info()) {</div><div class="line"><a name="l00132"></a><span class="lineno"> 132</span>&#160; codec = media_info.audio_info().codec();</div><div class="line"><a name="l00133"></a><span class="lineno"> 133</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (media_info.has_text_info()) {</div><div class="line"><a name="l00134"></a><span class="lineno"> 134</span>&#160; codec = media_info.text_info().codec();</div><div class="line"><a name="l00135"></a><span class="lineno"> 135</span>&#160; }</div><div class="line"><a name="l00136"></a><span class="lineno"> 136</span>&#160; <span class="comment">// Convert, for example, &quot;mp4a.40.2&quot; to simply &quot;mp4a&quot;.</span></div><div class="line"><a name="l00137"></a><span class="lineno"> 137</span>&#160; <span class="comment">// &quot;mp4a.40.2&quot; and &quot;mp4a.40.5&quot; can exist in the same AdaptationSet.</span></div><div class="line"><a name="l00138"></a><span class="lineno"> 138</span>&#160; <span class="keywordtype">size_t</span> dot = codec.find(<span class="charliteral">&#39;.&#39;</span>);</div><div class="line"><a name="l00139"></a><span class="lineno"> 139</span>&#160; <span class="keywordflow">if</span> (dot != std::string::npos) {</div><div class="line"><a name="l00140"></a><span class="lineno"> 140</span>&#160; codec.erase(dot);</div><div class="line"><a name="l00141"></a><span class="lineno"> 141</span>&#160; }</div><div class="line"><a name="l00142"></a><span class="lineno"> 142</span>&#160; <span class="keywordflow">return</span> codec;</div><div class="line"><a name="l00143"></a><span class="lineno"> 143</span>&#160;}</div><div class="line"><a name="l00144"></a><span class="lineno"> 144</span>&#160;</div><div class="line"><a name="l00145"></a><span class="lineno"> 145</span>&#160;std::string GetAdaptationSetKey(<span class="keyword">const</span> MediaInfo&amp; media_info) {</div><div class="line"><a name="l00146"></a><span class="lineno"> 146</span>&#160; std::string key;</div><div class="line"><a name="l00147"></a><span class="lineno"> 147</span>&#160;</div><div class="line"><a name="l00148"></a><span class="lineno"> 148</span>&#160; <span class="keywordflow">if</span> (media_info.has_video_info()) {</div><div class="line"><a name="l00149"></a><span class="lineno"> 149</span>&#160; key.append(<span class="stringliteral">&quot;video:&quot;</span>);</div><div class="line"><a name="l00150"></a><span class="lineno"> 150</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (media_info.has_audio_info()) {</div><div class="line"><a name="l00151"></a><span class="lineno"> 151</span>&#160; key.append(<span class="stringliteral">&quot;audio:&quot;</span>);</div><div class="line"><a name="l00152"></a><span class="lineno"> 152</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (media_info.has_text_info()) {</div><div class="line"><a name="l00153"></a><span class="lineno"> 153</span>&#160; key.append(MediaInfo_TextInfo_TextType_Name(media_info.text_info().type()));</div><div class="line"><a name="l00154"></a><span class="lineno"> 154</span>&#160; key.append(<span class="stringliteral">&quot;:&quot;</span>);</div><div class="line"><a name="l00155"></a><span class="lineno"> 155</span>&#160; } <span class="keywordflow">else</span> {</div><div class="line"><a name="l00156"></a><span class="lineno"> 156</span>&#160; key.append(<span class="stringliteral">&quot;unknown:&quot;</span>);</div><div class="line"><a name="l00157"></a><span class="lineno"> 157</span>&#160; }</div><div class="line"><a name="l00158"></a><span class="lineno"> 158</span>&#160;</div><div class="line"><a name="l00159"></a><span class="lineno"> 159</span>&#160; key.append(MediaInfo_ContainerType_Name(media_info.container_type()));</div><div class="line"><a name="l00160"></a><span class="lineno"> 160</span>&#160; key.append(<span class="stringliteral">&quot;:&quot;</span>);</div><div class="line"><a name="l00161"></a><span class="lineno"> 161</span>&#160; key.append(GetBaseCodec(media_info));</div><div class="line"><a name="l00162"></a><span class="lineno"> 162</span>&#160; key.append(<span class="stringliteral">&quot;:&quot;</span>);</div><div class="line"><a name="l00163"></a><span class="lineno"> 163</span>&#160; key.append(GetLanguage(media_info));</div><div class="line"><a name="l00164"></a><span class="lineno"> 164</span>&#160;</div><div class="line"><a name="l00165"></a><span class="lineno"> 165</span>&#160; <span class="comment">// Trick play streams of the same original stream, but possibly with</span></div><div class="line"><a name="l00166"></a><span class="lineno"> 166</span>&#160; <span class="comment">// different trick_play_factors, belong to the same trick play AdaptationSet.</span></div><div class="line"><a name="l00167"></a><span class="lineno"> 167</span>&#160; <span class="keywordflow">if</span> (media_info.video_info().has_playback_rate()) {</div><div class="line"><a name="l00168"></a><span class="lineno"> 168</span>&#160; key.append(<span class="stringliteral">&quot;:trick_play&quot;</span>);</div><div class="line"><a name="l00169"></a><span class="lineno"> 169</span>&#160; }</div><div class="line"><a name="l00170"></a><span class="lineno"> 170</span>&#160;</div><div class="line"><a name="l00171"></a><span class="lineno"> 171</span>&#160; <span class="keywordflow">return</span> key;</div><div class="line"><a name="l00172"></a><span class="lineno"> 172</span>&#160;}</div><div class="line"><a name="l00173"></a><span class="lineno"> 173</span>&#160;</div><div class="line"><a name="l00174"></a><span class="lineno"> 174</span>&#160;std::string SecondsToXmlDuration(<span class="keywordtype">double</span> seconds) {</div><div class="line"><a name="l00175"></a><span class="lineno"> 175</span>&#160; <span class="comment">// Chrome internally uses time accurate to microseconds, which is implemented</span></div><div class="line"><a name="l00176"></a><span class="lineno"> 176</span>&#160; <span class="comment">// per MSE spec (https://www.w3.org/TR/media-source/).</span></div><div class="line"><a name="l00177"></a><span class="lineno"> 177</span>&#160; <span class="comment">// We need a string formatter that has at least microseconds accuracy for a</span></div><div class="line"><a name="l00178"></a><span class="lineno"> 178</span>&#160; <span class="comment">// normal video (with duration up to 3 hours). Chrome&#39;s DoubleToString</span></div><div class="line"><a name="l00179"></a><span class="lineno"> 179</span>&#160; <span class="comment">// implementation meets the requirement.</span></div><div class="line"><a name="l00180"></a><span class="lineno"> 180</span>&#160; <span class="keywordflow">return</span> <span class="stringliteral">&quot;PT&quot;</span> + base::DoubleToString(seconds) + <span class="stringliteral">&quot;S&quot;</span>;</div><div class="line"><a name="l00181"></a><span class="lineno"> 181</span>&#160;}</div><div class="line"><a name="l00182"></a><span class="lineno"> 182</span>&#160;</div><div class="line"><a name="l00183"></a><span class="lineno"> 183</span>&#160;<span class="keywordtype">bool</span> GetDurationAttribute(xmlNodePtr node, <span class="keywordtype">float</span>* duration) {</div><div class="line"><a name="l00184"></a><span class="lineno"> 184</span>&#160; DCHECK(node);</div><div class="line"><a name="l00185"></a><span class="lineno"> 185</span>&#160; DCHECK(duration);</div><div class="line"><a name="l00186"></a><span class="lineno"> 186</span>&#160; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> kDuration[] = <span class="stringliteral">&quot;duration&quot;</span>;</div><div class="line"><a name="l00187"></a><span class="lineno"> 187</span>&#160; xml::scoped_xml_ptr&lt;xmlChar&gt; duration_value(</div><div class="line"><a name="l00188"></a><span class="lineno"> 188</span>&#160; xmlGetProp(node, BAD_CAST kDuration));</div><div class="line"><a name="l00189"></a><span class="lineno"> 189</span>&#160;</div><div class="line"><a name="l00190"></a><span class="lineno"> 190</span>&#160; <span class="keywordflow">if</span> (!duration_value)</div><div class="line"><a name="l00191"></a><span class="lineno"> 191</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l00192"></a><span class="lineno"> 192</span>&#160;</div><div class="line"><a name="l00193"></a><span class="lineno"> 193</span>&#160; <span class="keywordtype">double</span> duration_double_precision = 0.0;</div><div class="line"><a name="l00194"></a><span class="lineno"> 194</span>&#160; <span class="keywordflow">if</span> (!base::StringToDouble(reinterpret_cast&lt;const char*&gt;(duration_value.get()),</div><div class="line"><a name="l00195"></a><span class="lineno"> 195</span>&#160; &amp;duration_double_precision)) {</div><div class="line"><a name="l00196"></a><span class="lineno"> 196</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l00197"></a><span class="lineno"> 197</span>&#160; }</div><div class="line"><a name="l00198"></a><span class="lineno"> 198</span>&#160;</div><div class="line"><a name="l00199"></a><span class="lineno"> 199</span>&#160; *duration = <span class="keyword">static_cast&lt;</span><span class="keywordtype">float</span><span class="keyword">&gt;</span>(duration_double_precision);</div><div class="line"><a name="l00200"></a><span class="lineno"> 200</span>&#160; <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l00201"></a><span class="lineno"> 201</span>&#160;}</div><div class="line"><a name="l00202"></a><span class="lineno"> 202</span>&#160;</div><div class="line"><a name="l00203"></a><span class="lineno"> 203</span>&#160;<span class="keywordtype">bool</span> MoreThanOneTrue(<span class="keywordtype">bool</span> b1, <span class="keywordtype">bool</span> b2, <span class="keywordtype">bool</span> b3) {</div><div class="line"><a name="l00204"></a><span class="lineno"> 204</span>&#160; <span class="keywordflow">return</span> (b1 &amp;&amp; b2) || (b2 &amp;&amp; b3) || (b3 &amp;&amp; b1);</div><div class="line"><a name="l00205"></a><span class="lineno"> 205</span>&#160;}</div><div class="line"><a name="l00206"></a><span class="lineno"> 206</span>&#160;</div><div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160;<span class="keywordtype">bool</span> AtLeastOneTrue(<span class="keywordtype">bool</span> b1, <span class="keywordtype">bool</span> b2, <span class="keywordtype">bool</span> b3) {</div><div class="line"><a name="l00208"></a><span class="lineno"> 208</span>&#160; <span class="keywordflow">return</span> b1 || b2 || b3;</div><div class="line"><a name="l00209"></a><span class="lineno"> 209</span>&#160;}</div><div class="line"><a name="l00210"></a><span class="lineno"> 210</span>&#160;</div><div class="line"><a name="l00211"></a><span class="lineno"> 211</span>&#160;<span class="keywordtype">bool</span> OnlyOneTrue(<span class="keywordtype">bool</span> b1, <span class="keywordtype">bool</span> b2, <span class="keywordtype">bool</span> b3) {</div><div class="line"><a name="l00212"></a><span class="lineno"> 212</span>&#160; <span class="keywordflow">return</span> !MoreThanOneTrue(b1, b2, b3) &amp;&amp; AtLeastOneTrue(b1, b2, b3);</div><div class="line"><a name="l00213"></a><span class="lineno"> 213</span>&#160;}</div><div class="line"><a name="l00214"></a><span class="lineno"> 214</span>&#160;</div><div class="line"><a name="l00215"></a><span class="lineno"> 215</span>&#160;<span class="comment">// Coverts binary data into human readable UUID format.</span></div><div class="line"><a name="l00216"></a><span class="lineno"><a class="line" href="../../d8/daf/namespaceshaka.html#a4c2ea2c3e7055657ca68a6b8e285d4d6"> 216</a></span>&#160;<span class="keywordtype">bool</span> <a class="code" href="../../d8/daf/namespaceshaka.html#a4c2ea2c3e7055657ca68a6b8e285d4d6">HexToUUID</a>(<span class="keyword">const</span> std::string&amp; data, std::string* uuid_format) {</div><div class="line"><a name="l00217"></a><span class="lineno"> 217</span>&#160; DCHECK(uuid_format);</div><div class="line"><a name="l00218"></a><span class="lineno"> 218</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> kExpectedUUIDSize = 16;</div><div class="line"><a name="l00219"></a><span class="lineno"> 219</span>&#160; <span class="keywordflow">if</span> (data.size() != kExpectedUUIDSize) {</div><div class="line"><a name="l00220"></a><span class="lineno"> 220</span>&#160; LOG(ERROR) &lt;&lt; <span class="stringliteral">&quot;UUID size is expected to be &quot;</span> &lt;&lt; kExpectedUUIDSize</div><div class="line"><a name="l00221"></a><span class="lineno"> 221</span>&#160; &lt;&lt; <span class="stringliteral">&quot; but is &quot;</span> &lt;&lt; data.size() &lt;&lt; <span class="stringliteral">&quot; and the data in hex is &quot;</span></div><div class="line"><a name="l00222"></a><span class="lineno"> 222</span>&#160; &lt;&lt; base::HexEncode(data.data(), data.size());</div><div class="line"><a name="l00223"></a><span class="lineno"> 223</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"><a name="l00224"></a><span class="lineno"> 224</span>&#160; }</div><div class="line"><a name="l00225"></a><span class="lineno"> 225</span>&#160;</div><div class="line"><a name="l00226"></a><span class="lineno"> 226</span>&#160; <span class="keyword">const</span> std::string hex_encoded =</div><div class="line"><a name="l00227"></a><span class="lineno"> 227</span>&#160; base::ToLowerASCII(base::HexEncode(data.data(), data.size()));</div><div class="line"><a name="l00228"></a><span class="lineno"> 228</span>&#160; DCHECK_EQ(hex_encoded.size(), kExpectedUUIDSize * 2);</div><div class="line"><a name="l00229"></a><span class="lineno"> 229</span>&#160; base::StringPiece all(hex_encoded);</div><div class="line"><a name="l00230"></a><span class="lineno"> 230</span>&#160; <span class="comment">// Note UUID has 5 parts separated with dashes.</span></div><div class="line"><a name="l00231"></a><span class="lineno"> 231</span>&#160; <span class="comment">// e.g. 123e4567-e89b-12d3-a456-426655440000</span></div><div class="line"><a name="l00232"></a><span class="lineno"> 232</span>&#160; <span class="comment">// These StringPieces have each part.</span></div><div class="line"><a name="l00233"></a><span class="lineno"> 233</span>&#160; base::StringPiece first = all.substr(0, 8);</div><div class="line"><a name="l00234"></a><span class="lineno"> 234</span>&#160; base::StringPiece second = all.substr(8, 4);</div><div class="line"><a name="l00235"></a><span class="lineno"> 235</span>&#160; base::StringPiece third = all.substr(12, 4);</div><div class="line"><a name="l00236"></a><span class="lineno"> 236</span>&#160; base::StringPiece fourth = all.substr(16, 4);</div><div class="line"><a name="l00237"></a><span class="lineno"> 237</span>&#160; base::StringPiece fifth = all.substr(20, 12);</div><div class="line"><a name="l00238"></a><span class="lineno"> 238</span>&#160;</div><div class="line"><a name="l00239"></a><span class="lineno"> 239</span>&#160; <span class="comment">// 32 hexadecimal characters with 4 hyphens.</span></div><div class="line"><a name="l00240"></a><span class="lineno"> 240</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> kHumanReadableUUIDSize = 36;</div><div class="line"><a name="l00241"></a><span class="lineno"> 241</span>&#160; uuid_format-&gt;reserve(kHumanReadableUUIDSize);</div><div class="line"><a name="l00242"></a><span class="lineno"> 242</span>&#160; first.CopyToString(uuid_format);</div><div class="line"><a name="l00243"></a><span class="lineno"> 243</span>&#160; uuid_format-&gt;append(<span class="stringliteral">&quot;-&quot;</span>);</div><div class="line"><a name="l00244"></a><span class="lineno"> 244</span>&#160; second.AppendToString(uuid_format);</div><div class="line"><a name="l00245"></a><span class="lineno"> 245</span>&#160; uuid_format-&gt;append(<span class="stringliteral">&quot;-&quot;</span>);</div><div class="line"><a name="l00246"></a><span class="lineno"> 246</span>&#160; third.AppendToString(uuid_format);</div><div class="line"><a name="l00247"></a><span class="lineno"> 247</span>&#160; uuid_format-&gt;append(<span class="stringliteral">&quot;-&quot;</span>);</div><div class="line"><a name="l00248"></a><span class="lineno"> 248</span>&#160; fourth.AppendToString(uuid_format);</div><div class="line"><a name="l00249"></a><span class="lineno"> 249</span>&#160; uuid_format-&gt;append(<span class="stringliteral">&quot;-&quot;</span>);</div><div class="line"><a name="l00250"></a><span class="lineno"> 250</span>&#160; fifth.AppendToString(uuid_format);</div><div class="line"><a name="l00251"></a><span class="lineno"> 251</span>&#160; <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l00252"></a><span class="lineno"> 252</span>&#160;}</div><div class="line"><a name="l00253"></a><span class="lineno"> 253</span>&#160;</div><div class="line"><a name="l00254"></a><span class="lineno"> 254</span>&#160;<span class="keywordtype">void</span> UpdateContentProtectionPsshHelper(</div><div class="line"><a name="l00255"></a><span class="lineno"> 255</span>&#160; <span class="keyword">const</span> std::string&amp; drm_uuid,</div><div class="line"><a name="l00256"></a><span class="lineno"> 256</span>&#160; <span class="keyword">const</span> std::string&amp; pssh,</div><div class="line"><a name="l00257"></a><span class="lineno"> 257</span>&#160; std::list&lt;ContentProtectionElement&gt;* content_protection_elements) {</div><div class="line"><a name="l00258"></a><span class="lineno"> 258</span>&#160; <span class="keyword">const</span> std::string drm_uuid_schemd_id_uri_form = <span class="stringliteral">&quot;urn:uuid:&quot;</span> + drm_uuid;</div><div class="line"><a name="l00259"></a><span class="lineno"> 259</span>&#160; <span class="keywordflow">for</span> (std::list&lt;ContentProtectionElement&gt;::iterator protection =</div><div class="line"><a name="l00260"></a><span class="lineno"> 260</span>&#160; content_protection_elements-&gt;begin();</div><div class="line"><a name="l00261"></a><span class="lineno"> 261</span>&#160; protection != content_protection_elements-&gt;end(); ++protection) {</div><div class="line"><a name="l00262"></a><span class="lineno"> 262</span>&#160; <span class="keywordflow">if</span> (protection-&gt;scheme_id_uri != drm_uuid_schemd_id_uri_form) {</div><div class="line"><a name="l00263"></a><span class="lineno"> 263</span>&#160; <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00264"></a><span class="lineno"> 264</span>&#160; }</div><div class="line"><a name="l00265"></a><span class="lineno"> 265</span>&#160;</div><div class="line"><a name="l00266"></a><span class="lineno"> 266</span>&#160; <span class="keywordflow">for</span> (std::vector&lt;Element&gt;::iterator subelement =</div><div class="line"><a name="l00267"></a><span class="lineno"> 267</span>&#160; protection-&gt;subelements.begin();</div><div class="line"><a name="l00268"></a><span class="lineno"> 268</span>&#160; subelement != protection-&gt;subelements.end(); ++subelement) {</div><div class="line"><a name="l00269"></a><span class="lineno"> 269</span>&#160; <span class="keywordflow">if</span> (subelement-&gt;name == kPsshElementName) {</div><div class="line"><a name="l00270"></a><span class="lineno"> 270</span>&#160; <span class="comment">// For now, we want to remove the PSSH element because some players do</span></div><div class="line"><a name="l00271"></a><span class="lineno"> 271</span>&#160; <span class="comment">// not support updating pssh.</span></div><div class="line"><a name="l00272"></a><span class="lineno"> 272</span>&#160; protection-&gt;subelements.erase(subelement);</div><div class="line"><a name="l00273"></a><span class="lineno"> 273</span>&#160;</div><div class="line"><a name="l00274"></a><span class="lineno"> 274</span>&#160; <span class="comment">// TODO(rkuroiwa): Uncomment this and remove the line above when</span></div><div class="line"><a name="l00275"></a><span class="lineno"> 275</span>&#160; <span class="comment">// shaka-player supports updating PSSH.</span></div><div class="line"><a name="l00276"></a><span class="lineno"> 276</span>&#160; <span class="comment">// subelement-&gt;content = pssh;</span></div><div class="line"><a name="l00277"></a><span class="lineno"> 277</span>&#160; <span class="keywordflow">return</span>;</div><div class="line"><a name="l00278"></a><span class="lineno"> 278</span>&#160; }</div><div class="line"><a name="l00279"></a><span class="lineno"> 279</span>&#160; }</div><div class="line"><a name="l00280"></a><span class="lineno"> 280</span>&#160;</div><div class="line"><a name="l00281"></a><span class="lineno"> 281</span>&#160; <span class="comment">// Reaching here means &lt;cenc:pssh&gt; does not exist under the</span></div><div class="line"><a name="l00282"></a><span class="lineno"> 282</span>&#160; <span class="comment">// ContentProtection element. Add it.</span></div><div class="line"><a name="l00283"></a><span class="lineno"> 283</span>&#160; <span class="comment">// TODO(rkuroiwa): Uncomment this when shaka-player supports updating PSSH.</span></div><div class="line"><a name="l00284"></a><span class="lineno"> 284</span>&#160; <span class="comment">// Element cenc_pssh;</span></div><div class="line"><a name="l00285"></a><span class="lineno"> 285</span>&#160; <span class="comment">// cenc_pssh.name = kPsshElementName;</span></div><div class="line"><a name="l00286"></a><span class="lineno"> 286</span>&#160; <span class="comment">// cenc_pssh.content = pssh;</span></div><div class="line"><a name="l00287"></a><span class="lineno"> 287</span>&#160; <span class="comment">// protection-&gt;subelements.push_back(cenc_pssh);</span></div><div class="line"><a name="l00288"></a><span class="lineno"> 288</span>&#160; <span class="keywordflow">return</span>;</div><div class="line"><a name="l00289"></a><span class="lineno"> 289</span>&#160; }</div><div class="line"><a name="l00290"></a><span class="lineno"> 290</span>&#160;</div><div class="line"><a name="l00291"></a><span class="lineno"> 291</span>&#160; <span class="comment">// Reaching here means that ContentProtection for the DRM does not exist.</span></div><div class="line"><a name="l00292"></a><span class="lineno"> 292</span>&#160; <span class="comment">// Add it.</span></div><div class="line"><a name="l00293"></a><span class="lineno"> 293</span>&#160; <a class="code" href="../../da/d43/structshaka_1_1ContentProtectionElement.html">ContentProtectionElement</a> content_protection;</div><div class="line"><a name="l00294"></a><span class="lineno"> 294</span>&#160; content_protection.scheme_id_uri = drm_uuid_schemd_id_uri_form;</div><div class="line"><a name="l00295"></a><span class="lineno"> 295</span>&#160; <span class="comment">// TODO(rkuroiwa): Uncomment this when shaka-player supports updating PSSH.</span></div><div class="line"><a name="l00296"></a><span class="lineno"> 296</span>&#160; <span class="comment">// Element cenc_pssh;</span></div><div class="line"><a name="l00297"></a><span class="lineno"> 297</span>&#160; <span class="comment">// cenc_pssh.name = kPsshElementName;</span></div><div class="line"><a name="l00298"></a><span class="lineno"> 298</span>&#160; <span class="comment">// cenc_pssh.content = pssh;</span></div><div class="line"><a name="l00299"></a><span class="lineno"> 299</span>&#160; <span class="comment">// content_protection.subelements.push_back(cenc_pssh);</span></div><div class="line"><a name="l00300"></a><span class="lineno"> 300</span>&#160; content_protection_elements-&gt;push_back(content_protection);</div><div class="line"><a name="l00301"></a><span class="lineno"> 301</span>&#160; <span class="keywordflow">return</span>;</div><div class="line"><a name="l00302"></a><span class="lineno"> 302</span>&#160;}</div><div class="line"><a name="l00303"></a><span class="lineno"> 303</span>&#160;</div><div class="line"><a name="l00304"></a><span class="lineno"> 304</span>&#160;<span class="keyword">namespace </span>{</div><div class="line"><a name="l00305"></a><span class="lineno"> 305</span>&#160;</div><div class="line"><a name="l00306"></a><span class="lineno"> 306</span>&#160;<span class="comment">// UUID for Marlin Adaptive Streaming Specification Simple Profile from</span></div><div class="line"><a name="l00307"></a><span class="lineno"> 307</span>&#160;<span class="comment">// https://dashif.org/identifiers/content_protection/.</span></div><div class="line"><a name="l00308"></a><span class="lineno"> 308</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span> kMarlinUUID[] = <span class="stringliteral">&quot;5e629af5-38da-4063-8977-97ffbd9902d4&quot;</span>;</div><div class="line"><a name="l00309"></a><span class="lineno"> 309</span>&#160;<span class="comment">// Unofficial FairPlay system id extracted from</span></div><div class="line"><a name="l00310"></a><span class="lineno"> 310</span>&#160;<span class="comment">// https://forums.developer.apple.com/thread/6185.</span></div><div class="line"><a name="l00311"></a><span class="lineno"> 311</span>&#160;<span class="keyword">const</span> <span class="keywordtype">char</span> kFairPlayUUID[] = <span class="stringliteral">&quot;29701fe4-3cc7-4a34-8c5b-ae90c7439a47&quot;</span>;</div><div class="line"><a name="l00312"></a><span class="lineno"> 312</span>&#160;</div><div class="line"><a name="l00313"></a><span class="lineno"> 313</span>&#160;<a class="code" href="../../de/da9/structshaka_1_1Element.html">Element</a> GenerateMarlinContentIds(<span class="keyword">const</span> std::string&amp; key_id) {</div><div class="line"><a name="l00314"></a><span class="lineno"> 314</span>&#160; <span class="comment">// See https://github.com/google/shaka-packager/issues/381 for details.</span></div><div class="line"><a name="l00315"></a><span class="lineno"> 315</span>&#160; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> kMarlinContentIdName[] = <span class="stringliteral">&quot;mas:MarlinContentId&quot;</span>;</div><div class="line"><a name="l00316"></a><span class="lineno"> 316</span>&#160; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> kMarlinContentIdPrefix[] = <span class="stringliteral">&quot;urn:marlin:kid:&quot;</span>;</div><div class="line"><a name="l00317"></a><span class="lineno"> 317</span>&#160; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> kMarlinContentIdsName[] = <span class="stringliteral">&quot;mas:MarlinContentIds&quot;</span>;</div><div class="line"><a name="l00318"></a><span class="lineno"> 318</span>&#160;</div><div class="line"><a name="l00319"></a><span class="lineno"> 319</span>&#160; <a class="code" href="../../de/da9/structshaka_1_1Element.html">Element</a> marlin_content_id;</div><div class="line"><a name="l00320"></a><span class="lineno"> 320</span>&#160; marlin_content_id.name = kMarlinContentIdName;</div><div class="line"><a name="l00321"></a><span class="lineno"> 321</span>&#160; marlin_content_id.content =</div><div class="line"><a name="l00322"></a><span class="lineno"> 322</span>&#160; kMarlinContentIdPrefix +</div><div class="line"><a name="l00323"></a><span class="lineno"> 323</span>&#160; base::ToLowerASCII(base::HexEncode(key_id.data(), key_id.size()));</div><div class="line"><a name="l00324"></a><span class="lineno"> 324</span>&#160;</div><div class="line"><a name="l00325"></a><span class="lineno"> 325</span>&#160; <a class="code" href="../../de/da9/structshaka_1_1Element.html">Element</a> marlin_content_ids;</div><div class="line"><a name="l00326"></a><span class="lineno"> 326</span>&#160; marlin_content_ids.name = kMarlinContentIdsName;</div><div class="line"><a name="l00327"></a><span class="lineno"> 327</span>&#160; marlin_content_ids.subelements.push_back(marlin_content_id);</div><div class="line"><a name="l00328"></a><span class="lineno"> 328</span>&#160;</div><div class="line"><a name="l00329"></a><span class="lineno"> 329</span>&#160; <span class="keywordflow">return</span> marlin_content_ids;</div><div class="line"><a name="l00330"></a><span class="lineno"> 330</span>&#160;}</div><div class="line"><a name="l00331"></a><span class="lineno"> 331</span>&#160;</div><div class="line"><a name="l00332"></a><span class="lineno"> 332</span>&#160;<a class="code" href="../../de/da9/structshaka_1_1Element.html">Element</a> GenerateCencPsshElement(<span class="keyword">const</span> std::string&amp; pssh) {</div><div class="line"><a name="l00333"></a><span class="lineno"> 333</span>&#160; std::string base64_encoded_pssh;</div><div class="line"><a name="l00334"></a><span class="lineno"> 334</span>&#160; base::Base64Encode(base::StringPiece(pssh.data(), pssh.size()),</div><div class="line"><a name="l00335"></a><span class="lineno"> 335</span>&#160; &amp;base64_encoded_pssh);</div><div class="line"><a name="l00336"></a><span class="lineno"> 336</span>&#160; <a class="code" href="../../de/da9/structshaka_1_1Element.html">Element</a> cenc_pssh;</div><div class="line"><a name="l00337"></a><span class="lineno"> 337</span>&#160; cenc_pssh.name = kPsshElementName;</div><div class="line"><a name="l00338"></a><span class="lineno"> 338</span>&#160; cenc_pssh.content = base64_encoded_pssh;</div><div class="line"><a name="l00339"></a><span class="lineno"> 339</span>&#160; <span class="keywordflow">return</span> cenc_pssh;</div><div class="line"><a name="l00340"></a><span class="lineno"> 340</span>&#160;}</div><div class="line"><a name="l00341"></a><span class="lineno"> 341</span>&#160;</div><div class="line"><a name="l00342"></a><span class="lineno"> 342</span>&#160;<span class="comment">// Helper function. This works because Representation and AdaptationSet both</span></div><div class="line"><a name="l00343"></a><span class="lineno"> 343</span>&#160;<span class="comment">// have AddContentProtectionElement().</span></div><div class="line"><a name="l00344"></a><span class="lineno"> 344</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> ContentProtectionParent&gt;</div><div class="line"><a name="l00345"></a><span class="lineno"> 345</span>&#160;<span class="keywordtype">void</span> AddContentProtectionElementsHelperTemplated(</div><div class="line"><a name="l00346"></a><span class="lineno"> 346</span>&#160; <span class="keyword">const</span> MediaInfo&amp; media_info,</div><div class="line"><a name="l00347"></a><span class="lineno"> 347</span>&#160; ContentProtectionParent* parent) {</div><div class="line"><a name="l00348"></a><span class="lineno"> 348</span>&#160; DCHECK(parent);</div><div class="line"><a name="l00349"></a><span class="lineno"> 349</span>&#160; <span class="keywordflow">if</span> (!media_info.has_protected_content())</div><div class="line"><a name="l00350"></a><span class="lineno"> 350</span>&#160; <span class="keywordflow">return</span>;</div><div class="line"><a name="l00351"></a><span class="lineno"> 351</span>&#160;</div><div class="line"><a name="l00352"></a><span class="lineno"> 352</span>&#160; <span class="keyword">const</span> MediaInfo::ProtectedContent&amp; protected_content =</div><div class="line"><a name="l00353"></a><span class="lineno"> 353</span>&#160; media_info.protected_content();</div><div class="line"><a name="l00354"></a><span class="lineno"> 354</span>&#160;</div><div class="line"><a name="l00355"></a><span class="lineno"> 355</span>&#160; <span class="comment">// DASH MPD spec specifies a default ContentProtection element for ISO BMFF</span></div><div class="line"><a name="l00356"></a><span class="lineno"> 356</span>&#160; <span class="comment">// (MP4) files.</span></div><div class="line"><a name="l00357"></a><span class="lineno"> 357</span>&#160; <span class="keyword">const</span> <span class="keywordtype">bool</span> is_mp4_container =</div><div class="line"><a name="l00358"></a><span class="lineno"> 358</span>&#160; media_info.container_type() == MediaInfo::CONTAINER_MP4;</div><div class="line"><a name="l00359"></a><span class="lineno"> 359</span>&#160; std::string key_id_uuid_format;</div><div class="line"><a name="l00360"></a><span class="lineno"> 360</span>&#160; <span class="keywordflow">if</span> (protected_content.has_default_key_id() &amp;&amp;</div><div class="line"><a name="l00361"></a><span class="lineno"> 361</span>&#160; !IsKeyRotationDefaultKeyId(protected_content.default_key_id())) {</div><div class="line"><a name="l00362"></a><span class="lineno"> 362</span>&#160; <span class="keywordflow">if</span> (!<a class="code" href="../../d8/daf/namespaceshaka.html#a4c2ea2c3e7055657ca68a6b8e285d4d6">HexToUUID</a>(protected_content.default_key_id(), &amp;key_id_uuid_format)) {</div><div class="line"><a name="l00363"></a><span class="lineno"> 363</span>&#160; LOG(ERROR) &lt;&lt; <span class="stringliteral">&quot;Failed to convert default key ID into UUID format.&quot;</span>;</div><div class="line"><a name="l00364"></a><span class="lineno"> 364</span>&#160; }</div><div class="line"><a name="l00365"></a><span class="lineno"> 365</span>&#160; }</div><div class="line"><a name="l00366"></a><span class="lineno"> 366</span>&#160;</div><div class="line"><a name="l00367"></a><span class="lineno"> 367</span>&#160; <span class="keywordflow">if</span> (is_mp4_container) {</div><div class="line"><a name="l00368"></a><span class="lineno"> 368</span>&#160; <a class="code" href="../../da/d43/structshaka_1_1ContentProtectionElement.html">ContentProtectionElement</a> mp4_content_protection;</div><div class="line"><a name="l00369"></a><span class="lineno"> 369</span>&#160; mp4_content_protection.scheme_id_uri = kEncryptedMp4Scheme;</div><div class="line"><a name="l00370"></a><span class="lineno"> 370</span>&#160; mp4_content_protection.value = protected_content.protection_scheme();</div><div class="line"><a name="l00371"></a><span class="lineno"> 371</span>&#160; <span class="keywordflow">if</span> (!key_id_uuid_format.empty()) {</div><div class="line"><a name="l00372"></a><span class="lineno"> 372</span>&#160; mp4_content_protection.additional_attributes[<span class="stringliteral">&quot;cenc:default_KID&quot;</span>] =</div><div class="line"><a name="l00373"></a><span class="lineno"> 373</span>&#160; key_id_uuid_format;</div><div class="line"><a name="l00374"></a><span class="lineno"> 374</span>&#160; }</div><div class="line"><a name="l00375"></a><span class="lineno"> 375</span>&#160;</div><div class="line"><a name="l00376"></a><span class="lineno"> 376</span>&#160; parent-&gt;AddContentProtectionElement(mp4_content_protection);</div><div class="line"><a name="l00377"></a><span class="lineno"> 377</span>&#160; }</div><div class="line"><a name="l00378"></a><span class="lineno"> 378</span>&#160;</div><div class="line"><a name="l00379"></a><span class="lineno"> 379</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; entry : protected_content.content_protection_entry()) {</div><div class="line"><a name="l00380"></a><span class="lineno"> 380</span>&#160; <span class="keywordflow">if</span> (!entry.has_uuid()) {</div><div class="line"><a name="l00381"></a><span class="lineno"> 381</span>&#160; LOG(WARNING)</div><div class="line"><a name="l00382"></a><span class="lineno"> 382</span>&#160; &lt;&lt; <span class="stringliteral">&quot;ContentProtectionEntry was specified but no UUID is set for &quot;</span></div><div class="line"><a name="l00383"></a><span class="lineno"> 383</span>&#160; &lt;&lt; entry.name_version() &lt;&lt; <span class="stringliteral">&quot;, skipping.&quot;</span>;</div><div class="line"><a name="l00384"></a><span class="lineno"> 384</span>&#160; <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00385"></a><span class="lineno"> 385</span>&#160; }</div><div class="line"><a name="l00386"></a><span class="lineno"> 386</span>&#160;</div><div class="line"><a name="l00387"></a><span class="lineno"> 387</span>&#160; <a class="code" href="../../da/d43/structshaka_1_1ContentProtectionElement.html">ContentProtectionElement</a> drm_content_protection;</div><div class="line"><a name="l00388"></a><span class="lineno"> 388</span>&#160;</div><div class="line"><a name="l00389"></a><span class="lineno"> 389</span>&#160; <span class="keywordflow">if</span> (entry.has_name_version())</div><div class="line"><a name="l00390"></a><span class="lineno"> 390</span>&#160; drm_content_protection.value = entry.name_version();</div><div class="line"><a name="l00391"></a><span class="lineno"> 391</span>&#160;</div><div class="line"><a name="l00392"></a><span class="lineno"> 392</span>&#160; <span class="keywordflow">if</span> (entry.uuid() == kFairPlayUUID) {</div><div class="line"><a name="l00393"></a><span class="lineno"> 393</span>&#160; VLOG(1) &lt;&lt; <span class="stringliteral">&quot;Skipping FairPlay ContentProtection element as FairPlay does &quot;</span></div><div class="line"><a name="l00394"></a><span class="lineno"> 394</span>&#160; <span class="stringliteral">&quot;not support DASH signaling.&quot;</span>;</div><div class="line"><a name="l00395"></a><span class="lineno"> 395</span>&#160; <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00396"></a><span class="lineno"> 396</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (entry.uuid() == kMarlinUUID) {</div><div class="line"><a name="l00397"></a><span class="lineno"> 397</span>&#160; <span class="comment">// Marlin requires its uuid to be in upper case. See #525 for details.</span></div><div class="line"><a name="l00398"></a><span class="lineno"> 398</span>&#160; drm_content_protection.scheme_id_uri =</div><div class="line"><a name="l00399"></a><span class="lineno"> 399</span>&#160; <span class="stringliteral">&quot;urn:uuid:&quot;</span> + base::ToUpperASCII(entry.uuid());</div><div class="line"><a name="l00400"></a><span class="lineno"> 400</span>&#160; drm_content_protection.subelements.push_back(</div><div class="line"><a name="l00401"></a><span class="lineno"> 401</span>&#160; GenerateMarlinContentIds(protected_content.default_key_id()));</div><div class="line"><a name="l00402"></a><span class="lineno"> 402</span>&#160; } <span class="keywordflow">else</span> {</div><div class="line"><a name="l00403"></a><span class="lineno"> 403</span>&#160; drm_content_protection.scheme_id_uri = <span class="stringliteral">&quot;urn:uuid:&quot;</span> + entry.uuid();</div><div class="line"><a name="l00404"></a><span class="lineno"> 404</span>&#160; <span class="keywordflow">if</span> (!entry.pssh().empty()) {</div><div class="line"><a name="l00405"></a><span class="lineno"> 405</span>&#160; drm_content_protection.subelements.push_back(</div><div class="line"><a name="l00406"></a><span class="lineno"> 406</span>&#160; GenerateCencPsshElement(entry.pssh()));</div><div class="line"><a name="l00407"></a><span class="lineno"> 407</span>&#160; }</div><div class="line"><a name="l00408"></a><span class="lineno"> 408</span>&#160; }</div><div class="line"><a name="l00409"></a><span class="lineno"> 409</span>&#160;</div><div class="line"><a name="l00410"></a><span class="lineno"> 410</span>&#160; <span class="keywordflow">if</span> (!key_id_uuid_format.empty() &amp;&amp; !is_mp4_container) {</div><div class="line"><a name="l00411"></a><span class="lineno"> 411</span>&#160; drm_content_protection.additional_attributes[<span class="stringliteral">&quot;cenc:default_KID&quot;</span>] =</div><div class="line"><a name="l00412"></a><span class="lineno"> 412</span>&#160; key_id_uuid_format;</div><div class="line"><a name="l00413"></a><span class="lineno"> 413</span>&#160; }</div><div class="line"><a name="l00414"></a><span class="lineno"> 414</span>&#160;</div><div class="line"><a name="l00415"></a><span class="lineno"> 415</span>&#160; parent-&gt;AddContentProtectionElement(drm_content_protection);</div><div class="line"><a name="l00416"></a><span class="lineno"> 416</span>&#160; }</div><div class="line"><a name="l00417"></a><span class="lineno"> 417</span>&#160;</div><div class="line"><a name="l00418"></a><span class="lineno"> 418</span>&#160; VLOG_IF(1, protected_content.content_protection_entry().size() == 0)</div><div class="line"><a name="l00419"></a><span class="lineno"> 419</span>&#160; &lt;&lt; <span class="stringliteral">&quot;The media is encrypted but no content protection specified (can &quot;</span></div><div class="line"><a name="l00420"></a><span class="lineno"> 420</span>&#160; <span class="stringliteral">&quot;happen with key rotation).&quot;</span>;</div><div class="line"><a name="l00421"></a><span class="lineno"> 421</span>&#160;}</div><div class="line"><a name="l00422"></a><span class="lineno"> 422</span>&#160;} <span class="comment">// namespace</span></div><div class="line"><a name="l00423"></a><span class="lineno"> 423</span>&#160;</div><div class="line"><a name="l00424"></a><span class="lineno"><a class="line" href="../../d8/daf/namespaceshaka.html#abfd977a0dfb051a942d1694442692814"> 424</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="../../d8/daf/namespaceshaka.html#abfd977a0dfb051a942d1694442692814">AddContentProtectionElements</a>(<span class="keyword">const</span> MediaInfo&amp; media_info,</div><div class="line"><a name="l00425"></a><span class="lineno"> 425</span>&#160; <a class="code" href="../../de/d52/classshaka_1_1Representation.html">Representation</a>* parent) {</div><div class="line"><a name="l00426"></a><span class="lineno"> 426</span>&#160; AddContentProtectionElementsHelperTemplated(media_info, parent);</div><div class="line"><a name="l00427"></a><span class="lineno"> 427</span>&#160;}</div><div class="line"><a name="l00428"></a><span class="lineno"> 428</span>&#160;</div><div class="line"><a name="l00429"></a><span class="lineno"><a class="line" href="../../d8/daf/namespaceshaka.html#ac917945d578a03ce53b902f6c1bc4e33"> 429</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="../../d8/daf/namespaceshaka.html#abfd977a0dfb051a942d1694442692814">AddContentProtectionElements</a>(<span class="keyword">const</span> MediaInfo&amp; media_info,</div><div class="line"><a name="l00430"></a><span class="lineno"> 430</span>&#160; <a class="code" href="../../d8/d8e/classshaka_1_1AdaptationSet.html">AdaptationSet</a>* parent) {</div><div class="line"><a name="l00431"></a><span class="lineno"> 431</span>&#160; AddContentProtectionElementsHelperTemplated(media_info, parent);</div><div class="line"><a name="l00432"></a><span class="lineno"> 432</span>&#160;}</div><div class="line"><a name="l00433"></a><span class="lineno"> 433</span>&#160;</div><div class="line"><a name="l00434"></a><span class="lineno"> 434</span>&#160;} <span class="comment">// namespace shaka</span></div><div class="ttc" id="classshaka_1_1AdaptationSet_html"><div class="ttname"><a href="../../d8/d8e/classshaka_1_1AdaptationSet.html">shaka::AdaptationSet</a></div><div class="ttdef"><b>Definition:</b> <a href="../../d8/d72/adaptation__set_8h_source.html#l00037">adaptation_set.h:37</a></div></div>
<div class="ttc" id="structshaka_1_1Element_html"><div class="ttname"><a href="../../de/da9/structshaka_1_1Element.html">shaka::Element</a></div><div class="ttdef"><b>Definition:</b> <a href="../../de/dd6/content__protection__element_8h_source.html#l00022">content_protection_element.h:22</a></div></div>
<div class="ttc" id="namespaceshaka_html_a5f657931280fdf63cae2ed8a8f891288"><div class="ttname"><a href="../../d8/daf/namespaceshaka.html#a5f657931280fdf63cae2ed8a8f891288">shaka::LanguageToShortestForm</a></div><div class="ttdeci">std::string LanguageToShortestForm(const std::string &amp;language)</div><div class="ttdef"><b>Definition:</b> <a href="../../d1/d72/language__utils_8cc_source.html#l00089">language_utils.cc:89</a></div></div>
<div class="ttc" id="namespaceshaka_html"><div class="ttname"><a href="../../d8/daf/namespaceshaka.html">shaka</a></div><div class="ttdoc">All the methods that are virtual are virtual for mocking. </div><div class="ttdef"><b>Definition:</b> <a href="../../d4/d15/gflags__hex__bytes_8cc_source.html#l00011">gflags_hex_bytes.cc:11</a></div></div>
<div class="ttc" id="structshaka_1_1ContentProtectionElement_html"><div class="ttname"><a href="../../da/d43/structshaka_1_1ContentProtectionElement.html">shaka::ContentProtectionElement</a></div><div class="ttdef"><b>Definition:</b> <a href="../../de/dd6/content__protection__element_8h_source.html#l00036">content_protection_element.h:36</a></div></div>
<div class="ttc" id="namespaceshaka_html_abfd977a0dfb051a942d1694442692814"><div class="ttname"><a href="../../d8/daf/namespaceshaka.html#abfd977a0dfb051a942d1694442692814">shaka::AddContentProtectionElements</a></div><div class="ttdeci">void AddContentProtectionElements(const MediaInfo &amp;media_info, Representation *parent)</div><div class="ttdef"><b>Definition:</b> <a href="../../db/dfb/mpd__utils_8cc_source.html#l00424">mpd_utils.cc:424</a></div></div>
<div class="ttc" id="namespaceshaka_html_a4c2ea2c3e7055657ca68a6b8e285d4d6"><div class="ttname"><a href="../../d8/daf/namespaceshaka.html#a4c2ea2c3e7055657ca68a6b8e285d4d6">shaka::HexToUUID</a></div><div class="ttdeci">bool HexToUUID(const std::string &amp;data, std::string *uuid_format)</div><div class="ttdef"><b>Definition:</b> <a href="../../db/dfb/mpd__utils_8cc_source.html#l00216">mpd_utils.cc:216</a></div></div>
<div class="ttc" id="classshaka_1_1Representation_html"><div class="ttname"><a href="../../de/d52/classshaka_1_1Representation.html">shaka::Representation</a></div><div class="ttdef"><b>Definition:</b> <a href="../../d0/d2b/representation_8h_source.html#l00054">representation.h:54</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Dec 20 2018 14:37:38 for Shaka Packager SDK by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>