shaka-packager/docs/d3/d9c/encryption__handler_8cc_sou...

506 lines
70 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" "https://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.17"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Shaka Packager SDK: packager/media/crypto/encryption_handler.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.17 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('../../',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</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_f99dae54fe7170f791f339b952d5067a.html">media</a></li><li class="navelem"><a class="el" href="../../dir_aa847bee70cdde822696c7e33a504139.html">crypto</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">encryption_handler.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 2017 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/media/crypto/encryption_handler.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;stddef.h&gt;</span></div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160;<span class="preprocessor">#include &lt;stdint.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 &lt;algorithm&gt;</span></div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span>&#160; </div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/aes_encryptor.h&quot;</span></div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/audio_stream_info.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/common_pssh_generator.h&quot;</span></div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/key_source.h&quot;</span></div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/macros.h&quot;</span></div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/media_sample.h&quot;</span></div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/playready_pssh_generator.h&quot;</span></div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/protection_system_ids.h&quot;</span></div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/video_stream_info.h&quot;</span></div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/widevine_pssh_generator.h&quot;</span></div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span>&#160;<span class="preprocessor">#include &quot;packager/media/crypto/aes_encryptor_factory.h&quot;</span></div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span>&#160;<span class="preprocessor">#include &quot;packager/media/crypto/subsample_generator.h&quot;</span></div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span>&#160;<span class="preprocessor">#include &quot;packager/status_macros.h&quot;</span></div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span>&#160; </div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>&#160;<span class="keyword">namespace </span><a class="code" href="../../d8/daf/namespaceshaka.html">shaka</a> {</div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span>&#160;<span class="keyword">namespace </span>media {</div>
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span>&#160; </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;<span class="comment">// The encryption handler only supports a single output.</span></div>
<div class="line"><a name="l00033"></a><span class="lineno"> 33</span>&#160;<span class="keyword">const</span> <span class="keywordtype">size_t</span> kStreamIndex = 0;</div>
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span>&#160; </div>
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span>&#160;<span class="comment">// The default KID, KEY and IV for key rotation are all 0s.</span></div>
<div class="line"><a name="l00036"></a><span class="lineno"> 36</span>&#160;<span class="comment">// They are placeholders and are not really being used to encrypt data.</span></div>
<div class="line"><a name="l00037"></a><span class="lineno"> 37</span>&#160;<span class="keyword">const</span> uint8_t kKeyRotationDefaultKeyId[] = {</div>
<div class="line"><a name="l00038"></a><span class="lineno"> 38</span>&#160; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,</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;<span class="keyword">const</span> uint8_t kKeyRotationDefaultKey[] = {</div>
<div class="line"><a name="l00041"></a><span class="lineno"> 41</span>&#160; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,</div>
<div class="line"><a name="l00042"></a><span class="lineno"> 42</span>&#160;};</div>
<div class="line"><a name="l00043"></a><span class="lineno"> 43</span>&#160;<span class="keyword">const</span> uint8_t kKeyRotationDefaultIv[] = {</div>
<div class="line"><a name="l00044"></a><span class="lineno"> 44</span>&#160; 0, 0, 0, 0, 0, 0, 0, 0,</div>
<div class="line"><a name="l00045"></a><span class="lineno"> 45</span>&#160;};</div>
<div class="line"><a name="l00046"></a><span class="lineno"> 46</span>&#160; </div>
<div class="line"><a name="l00047"></a><span class="lineno"> 47</span>&#160;std::string GetStreamLabelForEncryption(</div>
<div class="line"><a name="l00048"></a><span class="lineno"> 48</span>&#160; <span class="keyword">const</span> StreamInfo&amp; stream_info,</div>
<div class="line"><a name="l00049"></a><span class="lineno"> 49</span>&#160; <span class="keyword">const</span> std::function&lt;std::string(</div>
<div class="line"><a name="l00050"></a><span class="lineno"> 50</span>&#160; <span class="keyword">const</span> EncryptionParams::EncryptedStreamAttributes&amp; stream_attributes)&gt;&amp;</div>
<div class="line"><a name="l00051"></a><span class="lineno"> 51</span>&#160; stream_label_func) {</div>
<div class="line"><a name="l00052"></a><span class="lineno"> 52</span>&#160; EncryptionParams::EncryptedStreamAttributes stream_attributes;</div>
<div class="line"><a name="l00053"></a><span class="lineno"> 53</span>&#160; <span class="keywordflow">if</span> (stream_info.stream_type() == kStreamAudio) {</div>
<div class="line"><a name="l00054"></a><span class="lineno"> 54</span>&#160; stream_attributes.stream_type =</div>
<div class="line"><a name="l00055"></a><span class="lineno"> 55</span>&#160; EncryptionParams::EncryptedStreamAttributes::kAudio;</div>
<div class="line"><a name="l00056"></a><span class="lineno"> 56</span>&#160; } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (stream_info.stream_type() == kStreamVideo) {</div>
<div class="line"><a name="l00057"></a><span class="lineno"> 57</span>&#160; <span class="keyword">const</span> VideoStreamInfo&amp; video_stream_info =</div>
<div class="line"><a name="l00058"></a><span class="lineno"> 58</span>&#160; <span class="keyword">static_cast&lt;</span><span class="keyword">const </span>VideoStreamInfo&amp;<span class="keyword">&gt;</span>(stream_info);</div>
<div class="line"><a name="l00059"></a><span class="lineno"> 59</span>&#160; stream_attributes.stream_type =</div>
<div class="line"><a name="l00060"></a><span class="lineno"> 60</span>&#160; EncryptionParams::EncryptedStreamAttributes::kVideo;</div>
<div class="line"><a name="l00061"></a><span class="lineno"> 61</span>&#160; stream_attributes.oneof.video.width = video_stream_info.width();</div>
<div class="line"><a name="l00062"></a><span class="lineno"> 62</span>&#160; stream_attributes.oneof.video.height = video_stream_info.height();</div>
<div class="line"><a name="l00063"></a><span class="lineno"> 63</span>&#160; }</div>
<div class="line"><a name="l00064"></a><span class="lineno"> 64</span>&#160; <span class="keywordflow">return</span> stream_label_func(stream_attributes);</div>
<div class="line"><a name="l00065"></a><span class="lineno"> 65</span>&#160;}</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;<span class="keywordtype">bool</span> IsPatternEncryptionScheme(FourCC protection_scheme) {</div>
<div class="line"><a name="l00068"></a><span class="lineno"> 68</span>&#160; <span class="keywordflow">return</span> protection_scheme == kAppleSampleAesProtectionScheme ||</div>
<div class="line"><a name="l00069"></a><span class="lineno"> 69</span>&#160; protection_scheme == FOURCC_cbcs || protection_scheme == FOURCC_cens;</div>
<div class="line"><a name="l00070"></a><span class="lineno"> 70</span>&#160;}</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;<span class="keywordtype">void</span> FillPsshGenerators(</div>
<div class="line"><a name="l00073"></a><span class="lineno"> 73</span>&#160; <span class="keyword">const</span> EncryptionParams&amp; encryption_params,</div>
<div class="line"><a name="l00074"></a><span class="lineno"> 74</span>&#160; std::vector&lt;std::unique_ptr&lt;PsshGenerator&gt;&gt;* pssh_generators,</div>
<div class="line"><a name="l00075"></a><span class="lineno"> 75</span>&#160; std::vector&lt;std::vector&lt;uint8_t&gt;&gt;* no_pssh_systems) {</div>
<div class="line"><a name="l00076"></a><span class="lineno"> 76</span>&#160; <span class="keywordflow">if</span> (has_flag(encryption_params.protection_systems,</div>
<div class="line"><a name="l00077"></a><span class="lineno"> 77</span>&#160; <a class="code" href="../../d8/daf/namespaceshaka.html#aadc0cc211185374c4bf219da325673aca4a8a926ca6c8454f8249deec51b47e66">ProtectionSystem::kCommon</a>)) {</div>
<div class="line"><a name="l00078"></a><span class="lineno"> 78</span>&#160; pssh_generators-&gt;emplace_back(<span class="keyword">new</span> CommonPsshGenerator());</div>
<div class="line"><a name="l00079"></a><span class="lineno"> 79</span>&#160; }</div>
<div class="line"><a name="l00080"></a><span class="lineno"> 80</span>&#160; </div>
<div class="line"><a name="l00081"></a><span class="lineno"> 81</span>&#160; <span class="keywordflow">if</span> (has_flag(encryption_params.protection_systems,</div>
<div class="line"><a name="l00082"></a><span class="lineno"> 82</span>&#160; ProtectionSystem::kPlayReady)) {</div>
<div class="line"><a name="l00083"></a><span class="lineno"> 83</span>&#160; pssh_generators-&gt;emplace_back(<span class="keyword">new</span> PlayReadyPsshGenerator(</div>
<div class="line"><a name="l00084"></a><span class="lineno"> 84</span>&#160; encryption_params.playready_extra_header_data,</div>
<div class="line"><a name="l00085"></a><span class="lineno"> 85</span>&#160; <span class="keyword">static_cast&lt;</span>FourCC<span class="keyword">&gt;</span>(encryption_params.protection_scheme)));</div>
<div class="line"><a name="l00086"></a><span class="lineno"> 86</span>&#160; }</div>
<div class="line"><a name="l00087"></a><span class="lineno"> 87</span>&#160; </div>
<div class="line"><a name="l00088"></a><span class="lineno"> 88</span>&#160; <span class="keywordflow">if</span> (has_flag(encryption_params.protection_systems,</div>
<div class="line"><a name="l00089"></a><span class="lineno"> 89</span>&#160; ProtectionSystem::kWidevine)) {</div>
<div class="line"><a name="l00090"></a><span class="lineno"> 90</span>&#160; pssh_generators-&gt;emplace_back(<span class="keyword">new</span> WidevinePsshGenerator(</div>
<div class="line"><a name="l00091"></a><span class="lineno"> 91</span>&#160; <span class="keyword">static_cast&lt;</span>FourCC<span class="keyword">&gt;</span>(encryption_params.protection_scheme)));</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; </div>
<div class="line"><a name="l00094"></a><span class="lineno"> 94</span>&#160; <span class="keywordflow">if</span> (has_flag(encryption_params.protection_systems,</div>
<div class="line"><a name="l00095"></a><span class="lineno"> 95</span>&#160; ProtectionSystem::kFairPlay)) {</div>
<div class="line"><a name="l00096"></a><span class="lineno"> 96</span>&#160; no_pssh_systems-&gt;emplace_back(std::begin(kFairPlaySystemId),</div>
<div class="line"><a name="l00097"></a><span class="lineno"> 97</span>&#160; std::end(kFairPlaySystemId));</div>
<div class="line"><a name="l00098"></a><span class="lineno"> 98</span>&#160; }</div>
<div class="line"><a name="l00099"></a><span class="lineno"> 99</span>&#160; <span class="comment">// We only support Marlin Adaptive Streaming Specification Simple Profile</span></div>
<div class="line"><a name="l00100"></a><span class="lineno"> 100</span>&#160; <span class="comment">// with Implicit Content ID Mapping, which does not need a PSSH. Marlin</span></div>
<div class="line"><a name="l00101"></a><span class="lineno"> 101</span>&#160; <span class="comment">// specific PSSH with Explicit Content ID Mapping is not generated.</span></div>
<div class="line"><a name="l00102"></a><span class="lineno"> 102</span>&#160; <span class="keywordflow">if</span> (has_flag(encryption_params.protection_systems,</div>
<div class="line"><a name="l00103"></a><span class="lineno"> 103</span>&#160; ProtectionSystem::kMarlin)) {</div>
<div class="line"><a name="l00104"></a><span class="lineno"> 104</span>&#160; no_pssh_systems-&gt;emplace_back(std::begin(kMarlinSystemId),</div>
<div class="line"><a name="l00105"></a><span class="lineno"> 105</span>&#160; std::end(kMarlinSystemId));</div>
<div class="line"><a name="l00106"></a><span class="lineno"> 106</span>&#160; }</div>
<div class="line"><a name="l00107"></a><span class="lineno"> 107</span>&#160; </div>
<div class="line"><a name="l00108"></a><span class="lineno"> 108</span>&#160; <span class="keywordflow">if</span> (pssh_generators-&gt;empty() &amp;&amp; no_pssh_systems-&gt;empty() &amp;&amp;</div>
<div class="line"><a name="l00109"></a><span class="lineno"> 109</span>&#160; (encryption_params.key_provider != KeyProvider::kRawKey ||</div>
<div class="line"><a name="l00110"></a><span class="lineno"> 110</span>&#160; encryption_params.raw_key.pssh.empty())) {</div>
<div class="line"><a name="l00111"></a><span class="lineno"> 111</span>&#160; pssh_generators-&gt;emplace_back(<span class="keyword">new</span> CommonPsshGenerator());</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; </div>
<div class="line"><a name="l00115"></a><span class="lineno"> 115</span>&#160;<span class="keywordtype">void</span> AddProtectionSystemIfNotExist(</div>
<div class="line"><a name="l00116"></a><span class="lineno"> 116</span>&#160; <span class="keyword">const</span> ProtectionSystemSpecificInfo&amp; pssh_info,</div>
<div class="line"><a name="l00117"></a><span class="lineno"> 117</span>&#160; EncryptionConfig* encryption_config) {</div>
<div class="line"><a name="l00118"></a><span class="lineno"> 118</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; info : encryption_config-&gt;key_system_info) {</div>
<div class="line"><a name="l00119"></a><span class="lineno"> 119</span>&#160; <span class="keywordflow">if</span> (info.system_id == pssh_info.system_id)</div>
<div class="line"><a name="l00120"></a><span class="lineno"> 120</span>&#160; <span class="keywordflow">return</span>;</div>
<div class="line"><a name="l00121"></a><span class="lineno"> 121</span>&#160; }</div>
<div class="line"><a name="l00122"></a><span class="lineno"> 122</span>&#160; encryption_config-&gt;key_system_info.push_back(pssh_info);</div>
<div class="line"><a name="l00123"></a><span class="lineno"> 123</span>&#160;}</div>
<div class="line"><a name="l00124"></a><span class="lineno"> 124</span>&#160; </div>
<div class="line"><a name="l00125"></a><span class="lineno"> 125</span>&#160;Status FillProtectionSystemInfo(<span class="keyword">const</span> EncryptionParams&amp; encryption_params,</div>
<div class="line"><a name="l00126"></a><span class="lineno"> 126</span>&#160; <span class="keyword">const</span> EncryptionKey&amp; encryption_key,</div>
<div class="line"><a name="l00127"></a><span class="lineno"> 127</span>&#160; EncryptionConfig* encryption_config) {</div>
<div class="line"><a name="l00128"></a><span class="lineno"> 128</span>&#160; <span class="comment">// If generating dummy keys for key rotation, don&#39;t generate PSSH info.</span></div>
<div class="line"><a name="l00129"></a><span class="lineno"> 129</span>&#160; <span class="keywordflow">if</span> (encryption_key.key_ids.empty())</div>
<div class="line"><a name="l00130"></a><span class="lineno"> 130</span>&#160; <span class="keywordflow">return</span> Status::OK;</div>
<div class="line"><a name="l00131"></a><span class="lineno"> 131</span>&#160; </div>
<div class="line"><a name="l00132"></a><span class="lineno"> 132</span>&#160; std::vector&lt;std::unique_ptr&lt;PsshGenerator&gt;&gt; pssh_generators;</div>
<div class="line"><a name="l00133"></a><span class="lineno"> 133</span>&#160; std::vector&lt;std::vector&lt;uint8_t&gt;&gt; no_pssh_systems;</div>
<div class="line"><a name="l00134"></a><span class="lineno"> 134</span>&#160; FillPsshGenerators(encryption_params, &amp;pssh_generators, &amp;no_pssh_systems);</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; encryption_config-&gt;key_system_info = encryption_key.key_system_info;</div>
<div class="line"><a name="l00137"></a><span class="lineno"> 137</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; pssh_generator : pssh_generators) {</div>
<div class="line"><a name="l00138"></a><span class="lineno"> 138</span>&#160; <span class="keyword">const</span> <span class="keywordtype">bool</span> support_multiple_keys = pssh_generator-&gt;SupportMultipleKeys();</div>
<div class="line"><a name="l00139"></a><span class="lineno"> 139</span>&#160; <span class="keywordflow">if</span> (support_multiple_keys) {</div>
<div class="line"><a name="l00140"></a><span class="lineno"> 140</span>&#160; ProtectionSystemSpecificInfo info;</div>
<div class="line"><a name="l00141"></a><span class="lineno"> 141</span>&#160; RETURN_IF_ERROR(pssh_generator-&gt;GeneratePsshFromKeyIds(</div>
<div class="line"><a name="l00142"></a><span class="lineno"> 142</span>&#160; encryption_key.key_ids, &amp;info));</div>
<div class="line"><a name="l00143"></a><span class="lineno"> 143</span>&#160; AddProtectionSystemIfNotExist(info, encryption_config);</div>
<div class="line"><a name="l00144"></a><span class="lineno"> 144</span>&#160; } <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00145"></a><span class="lineno"> 145</span>&#160; ProtectionSystemSpecificInfo info;</div>
<div class="line"><a name="l00146"></a><span class="lineno"> 146</span>&#160; RETURN_IF_ERROR(pssh_generator-&gt;GeneratePsshFromKeyIdAndKey(</div>
<div class="line"><a name="l00147"></a><span class="lineno"> 147</span>&#160; encryption_key.key_id, encryption_key.key, &amp;info));</div>
<div class="line"><a name="l00148"></a><span class="lineno"> 148</span>&#160; AddProtectionSystemIfNotExist(info, encryption_config);</div>
<div class="line"><a name="l00149"></a><span class="lineno"> 149</span>&#160; }</div>
<div class="line"><a name="l00150"></a><span class="lineno"> 150</span>&#160; }</div>
<div class="line"><a name="l00151"></a><span class="lineno"> 151</span>&#160; </div>
<div class="line"><a name="l00152"></a><span class="lineno"> 152</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <span class="keyword">auto</span>&amp; no_pssh_system : no_pssh_systems) {</div>
<div class="line"><a name="l00153"></a><span class="lineno"> 153</span>&#160; ProtectionSystemSpecificInfo info;</div>
<div class="line"><a name="l00154"></a><span class="lineno"> 154</span>&#160; info.system_id = no_pssh_system;</div>
<div class="line"><a name="l00155"></a><span class="lineno"> 155</span>&#160; AddProtectionSystemIfNotExist(info, encryption_config);</div>
<div class="line"><a name="l00156"></a><span class="lineno"> 156</span>&#160; }</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; <span class="keywordflow">return</span> Status::OK;</div>
<div class="line"><a name="l00159"></a><span class="lineno"> 159</span>&#160;}</div>
<div class="line"><a name="l00160"></a><span class="lineno"> 160</span>&#160; </div>
<div class="line"><a name="l00161"></a><span class="lineno"> 161</span>&#160;} <span class="comment">// namespace</span></div>
<div class="line"><a name="l00162"></a><span class="lineno"> 162</span>&#160; </div>
<div class="line"><a name="l00163"></a><span class="lineno"> 163</span>&#160;EncryptionHandler::EncryptionHandler(<span class="keyword">const</span> EncryptionParams&amp; encryption_params,</div>
<div class="line"><a name="l00164"></a><span class="lineno"> 164</span>&#160; KeySource* key_source)</div>
<div class="line"><a name="l00165"></a><span class="lineno"> 165</span>&#160; : encryption_params_(encryption_params),</div>
<div class="line"><a name="l00166"></a><span class="lineno"> 166</span>&#160; protection_scheme_(</div>
<div class="line"><a name="l00167"></a><span class="lineno"> 167</span>&#160; static_cast&lt;FourCC&gt;(encryption_params.protection_scheme)),</div>
<div class="line"><a name="l00168"></a><span class="lineno"> 168</span>&#160; key_source_(key_source),</div>
<div class="line"><a name="l00169"></a><span class="lineno"> 169</span>&#160; subsample_generator_(</div>
<div class="line"><a name="l00170"></a><span class="lineno"> 170</span>&#160; new SubsampleGenerator(encryption_params.vp9_subsample_encryption)),</div>
<div class="line"><a name="l00171"></a><span class="lineno"> 171</span>&#160; encryptor_factory_(new AesEncryptorFactory) {}</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;EncryptionHandler::~EncryptionHandler() = <span class="keywordflow">default</span>;</div>
<div class="line"><a name="l00174"></a><span class="lineno"> 174</span>&#160; </div>
<div class="line"><a name="l00175"></a><span class="lineno"><a class="line" href="../../d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html#a3f1808a4386081e5e1c9a798a1a69dd0"> 175</a></span>&#160;<a class="code" href="../../d2/d20/classshaka_1_1Status.html">Status</a> <a class="code" href="../../d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html#a3f1808a4386081e5e1c9a798a1a69dd0">EncryptionHandler::InitializeInternal</a>() {</div>
<div class="line"><a name="l00176"></a><span class="lineno"> 176</span>&#160; <span class="keywordflow">if</span> (!encryption_params_.<a class="code" href="../../dc/da0/structshaka_1_1EncryptionParams.html#a7686a6aca6a7c3d077a5d7215c39fc51">stream_label_func</a>) {</div>
<div class="line"><a name="l00177"></a><span class="lineno"> 177</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../d2/d20/classshaka_1_1Status.html">Status</a>(error::INVALID_ARGUMENT, <span class="stringliteral">&quot;Stream label function not set.&quot;</span>);</div>
<div class="line"><a name="l00178"></a><span class="lineno"> 178</span>&#160; }</div>
<div class="line"><a name="l00179"></a><span class="lineno"> 179</span>&#160; <span class="keywordflow">if</span> (num_input_streams() != 1 || next_output_stream_index() != 1) {</div>
<div class="line"><a name="l00180"></a><span class="lineno"> 180</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../d2/d20/classshaka_1_1Status.html">Status</a>(error::INVALID_ARGUMENT,</div>
<div class="line"><a name="l00181"></a><span class="lineno"> 181</span>&#160; <span class="stringliteral">&quot;Expects exactly one input and output.&quot;</span>);</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="keywordflow">return</span> Status::OK;</div>
<div class="line"><a name="l00184"></a><span class="lineno"> 184</span>&#160;}</div>
<div class="line"><a name="l00185"></a><span class="lineno"> 185</span>&#160; </div>
<div class="line"><a name="l00186"></a><span class="lineno"><a class="line" href="../../d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html#a7887e6060eb572036674ecb9a7e045c4"> 186</a></span>&#160;<a class="code" href="../../d2/d20/classshaka_1_1Status.html">Status</a> <a class="code" href="../../d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html#a7887e6060eb572036674ecb9a7e045c4">EncryptionHandler::Process</a>(std::unique_ptr&lt;StreamData&gt; stream_data) {</div>
<div class="line"><a name="l00187"></a><span class="lineno"> 187</span>&#160; <span class="keywordflow">switch</span> (stream_data-&gt;stream_data_type) {</div>
<div class="line"><a name="l00188"></a><span class="lineno"> 188</span>&#160; <span class="keywordflow">case</span> StreamDataType::kStreamInfo:</div>
<div class="line"><a name="l00189"></a><span class="lineno"> 189</span>&#160; <span class="keywordflow">return</span> ProcessStreamInfo(*stream_data-&gt;stream_info);</div>
<div class="line"><a name="l00190"></a><span class="lineno"> 190</span>&#160; <span class="keywordflow">case</span> StreamDataType::kSegmentInfo: {</div>
<div class="line"><a name="l00191"></a><span class="lineno"> 191</span>&#160; std::shared_ptr&lt;SegmentInfo&gt; segment_info(<span class="keyword">new</span> <a class="code" href="../../d0/dc0/structshaka_1_1media_1_1SegmentInfo.html">SegmentInfo</a>(</div>
<div class="line"><a name="l00192"></a><span class="lineno"> 192</span>&#160; *stream_data-&gt;segment_info));</div>
<div class="line"><a name="l00193"></a><span class="lineno"> 193</span>&#160; </div>
<div class="line"><a name="l00194"></a><span class="lineno"> 194</span>&#160; segment_info-&gt;is_encrypted = remaining_clear_lead_ &lt;= 0;</div>
<div class="line"><a name="l00195"></a><span class="lineno"> 195</span>&#160; </div>
<div class="line"><a name="l00196"></a><span class="lineno"> 196</span>&#160; <span class="keyword">const</span> <span class="keywordtype">bool</span> key_rotation_enabled = crypto_period_duration_ != 0;</div>
<div class="line"><a name="l00197"></a><span class="lineno"> 197</span>&#160; <span class="keywordflow">if</span> (key_rotation_enabled)</div>
<div class="line"><a name="l00198"></a><span class="lineno"> 198</span>&#160; segment_info-&gt;key_rotation_encryption_config = encryption_config_;</div>
<div class="line"><a name="l00199"></a><span class="lineno"> 199</span>&#160; <span class="keywordflow">if</span> (!segment_info-&gt;is_subsegment) {</div>
<div class="line"><a name="l00200"></a><span class="lineno"> 200</span>&#160; <span class="keywordflow">if</span> (key_rotation_enabled)</div>
<div class="line"><a name="l00201"></a><span class="lineno"> 201</span>&#160; check_new_crypto_period_ = <span class="keyword">true</span>;</div>
<div class="line"><a name="l00202"></a><span class="lineno"> 202</span>&#160; <span class="keywordflow">if</span> (remaining_clear_lead_ &gt; 0)</div>
<div class="line"><a name="l00203"></a><span class="lineno"> 203</span>&#160; remaining_clear_lead_ -= segment_info-&gt;duration;</div>
<div class="line"><a name="l00204"></a><span class="lineno"> 204</span>&#160; }</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; <span class="keywordflow">return</span> <a class="code" href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#a2acc1c84a61aee93229d493aa93308d5">DispatchSegmentInfo</a>(kStreamIndex, segment_info);</div>
<div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160; }</div>
<div class="line"><a name="l00208"></a><span class="lineno"> 208</span>&#160; <span class="keywordflow">case</span> StreamDataType::kMediaSample:</div>
<div class="line"><a name="l00209"></a><span class="lineno"> 209</span>&#160; <span class="keywordflow">return</span> ProcessMediaSample(std::move(stream_data-&gt;media_sample));</div>
<div class="line"><a name="l00210"></a><span class="lineno"> 210</span>&#160; <span class="keywordflow">default</span>:</div>
<div class="line"><a name="l00211"></a><span class="lineno"> 211</span>&#160; VLOG(3) &lt;&lt; <span class="stringliteral">&quot;Stream data type &quot;</span></div>
<div class="line"><a name="l00212"></a><span class="lineno"> 212</span>&#160; &lt;&lt; <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(stream_data-&gt;stream_data_type) &lt;&lt; <span class="stringliteral">&quot; ignored.&quot;</span>;</div>
<div class="line"><a name="l00213"></a><span class="lineno"> 213</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#afe98a4fd19eabe0fc78afc91959c34a6">Dispatch</a>(std::move(stream_data));</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;}</div>
<div class="line"><a name="l00216"></a><span class="lineno"> 216</span>&#160; </div>
<div class="line"><a name="l00217"></a><span class="lineno"> 217</span>&#160;<a class="code" href="../../d2/d20/classshaka_1_1Status.html">Status</a> EncryptionHandler::ProcessStreamInfo(<span class="keyword">const</span> <a class="code" href="../../d5/db1/classshaka_1_1media_1_1StreamInfo.html">StreamInfo</a>&amp; clear_info) {</div>
<div class="line"><a name="l00218"></a><span class="lineno"> 218</span>&#160; <span class="keywordflow">if</span> (clear_info.is_encrypted()) {</div>
<div class="line"><a name="l00219"></a><span class="lineno"> 219</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../d2/d20/classshaka_1_1Status.html">Status</a>(error::INVALID_ARGUMENT,</div>
<div class="line"><a name="l00220"></a><span class="lineno"> 220</span>&#160; <span class="stringliteral">&quot;Input stream is already encrypted.&quot;</span>);</div>
<div class="line"><a name="l00221"></a><span class="lineno"> 221</span>&#160; }</div>
<div class="line"><a name="l00222"></a><span class="lineno"> 222</span>&#160; </div>
<div class="line"><a name="l00223"></a><span class="lineno"> 223</span>&#160; DCHECK_NE(kStreamUnknown, clear_info.stream_type());</div>
<div class="line"><a name="l00224"></a><span class="lineno"> 224</span>&#160; DCHECK_NE(kStreamText, clear_info.stream_type());</div>
<div class="line"><a name="l00225"></a><span class="lineno"> 225</span>&#160; std::shared_ptr&lt;StreamInfo&gt; stream_info = clear_info.<a class="code" href="../../d5/db1/classshaka_1_1media_1_1StreamInfo.html#afdd9b2df8ae1c11bb033c44eaba5e38d">Clone</a>();</div>
<div class="line"><a name="l00226"></a><span class="lineno"> 226</span>&#160; RETURN_IF_ERROR(</div>
<div class="line"><a name="l00227"></a><span class="lineno"> 227</span>&#160; subsample_generator_-&gt;Initialize(protection_scheme_, *stream_info));</div>
<div class="line"><a name="l00228"></a><span class="lineno"> 228</span>&#160; </div>
<div class="line"><a name="l00229"></a><span class="lineno"> 229</span>&#160; remaining_clear_lead_ =</div>
<div class="line"><a name="l00230"></a><span class="lineno"> 230</span>&#160; encryption_params_.<a class="code" href="../../dc/da0/structshaka_1_1EncryptionParams.html#a1ad46963dc926aa4b72813dccb3f6a45">clear_lead_in_seconds</a> * stream_info-&gt;time_scale();</div>
<div class="line"><a name="l00231"></a><span class="lineno"> 231</span>&#160; crypto_period_duration_ =</div>
<div class="line"><a name="l00232"></a><span class="lineno"> 232</span>&#160; encryption_params_.crypto_period_duration_in_seconds *</div>
<div class="line"><a name="l00233"></a><span class="lineno"> 233</span>&#160; stream_info-&gt;time_scale();</div>
<div class="line"><a name="l00234"></a><span class="lineno"> 234</span>&#160; codec_ = stream_info-&gt;codec();</div>
<div class="line"><a name="l00235"></a><span class="lineno"> 235</span>&#160; stream_label_ = GetStreamLabelForEncryption(</div>
<div class="line"><a name="l00236"></a><span class="lineno"> 236</span>&#160; *stream_info, encryption_params_.<a class="code" href="../../dc/da0/structshaka_1_1EncryptionParams.html#a7686a6aca6a7c3d077a5d7215c39fc51">stream_label_func</a>);</div>
<div class="line"><a name="l00237"></a><span class="lineno"> 237</span>&#160; </div>
<div class="line"><a name="l00238"></a><span class="lineno"> 238</span>&#160; SetupProtectionPattern(stream_info-&gt;stream_type());</div>
<div class="line"><a name="l00239"></a><span class="lineno"> 239</span>&#160; </div>
<div class="line"><a name="l00240"></a><span class="lineno"> 240</span>&#160; EncryptionKey encryption_key;</div>
<div class="line"><a name="l00241"></a><span class="lineno"> 241</span>&#160; <span class="keyword">const</span> <span class="keywordtype">bool</span> key_rotation_enabled = crypto_period_duration_ != 0;</div>
<div class="line"><a name="l00242"></a><span class="lineno"> 242</span>&#160; <span class="keywordflow">if</span> (key_rotation_enabled) {</div>
<div class="line"><a name="l00243"></a><span class="lineno"> 243</span>&#160; check_new_crypto_period_ = <span class="keyword">true</span>;</div>
<div class="line"><a name="l00244"></a><span class="lineno"> 244</span>&#160; <span class="comment">// Setup dummy key id, key and iv to signal encryption for key rotation.</span></div>
<div class="line"><a name="l00245"></a><span class="lineno"> 245</span>&#160; encryption_key.key_id.assign(std::begin(kKeyRotationDefaultKeyId),</div>
<div class="line"><a name="l00246"></a><span class="lineno"> 246</span>&#160; std::end(kKeyRotationDefaultKeyId));</div>
<div class="line"><a name="l00247"></a><span class="lineno"> 247</span>&#160; encryption_key.key.assign(std::begin(kKeyRotationDefaultKey),</div>
<div class="line"><a name="l00248"></a><span class="lineno"> 248</span>&#160; std::end(kKeyRotationDefaultKey));</div>
<div class="line"><a name="l00249"></a><span class="lineno"> 249</span>&#160; encryption_key.iv.assign(std::begin(kKeyRotationDefaultIv),</div>
<div class="line"><a name="l00250"></a><span class="lineno"> 250</span>&#160; std::end(kKeyRotationDefaultIv));</div>
<div class="line"><a name="l00251"></a><span class="lineno"> 251</span>&#160; } <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00252"></a><span class="lineno"> 252</span>&#160; RETURN_IF_ERROR(key_source_-&gt;<a class="code" href="../../d1/d1f/classshaka_1_1media_1_1KeySource.html#af56c833453d65297c4dc96c9d2f83e1a">GetKey</a>(stream_label_, &amp;encryption_key));</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="keywordflow">if</span> (!CreateEncryptor(encryption_key))</div>
<div class="line"><a name="l00255"></a><span class="lineno"> 255</span>&#160; <span class="keywordflow">return</span> Status(error::ENCRYPTION_FAILURE, <span class="stringliteral">&quot;Failed to create encryptor&quot;</span>);</div>
<div class="line"><a name="l00256"></a><span class="lineno"> 256</span>&#160; </div>
<div class="line"><a name="l00257"></a><span class="lineno"> 257</span>&#160; stream_info-&gt;set_is_encrypted(<span class="keyword">true</span>);</div>
<div class="line"><a name="l00258"></a><span class="lineno"> 258</span>&#160; stream_info-&gt;set_has_clear_lead(encryption_params_.<a class="code" href="../../dc/da0/structshaka_1_1EncryptionParams.html#a1ad46963dc926aa4b72813dccb3f6a45">clear_lead_in_seconds</a> &gt; 0);</div>
<div class="line"><a name="l00259"></a><span class="lineno"> 259</span>&#160; stream_info-&gt;set_encryption_config(*encryption_config_);</div>
<div class="line"><a name="l00260"></a><span class="lineno"> 260</span>&#160; </div>
<div class="line"><a name="l00261"></a><span class="lineno"> 261</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#ad165375cd0a2074c5a740b42f847c499">DispatchStreamInfo</a>(kStreamIndex, stream_info);</div>
<div class="line"><a name="l00262"></a><span class="lineno"> 262</span>&#160;}</div>
<div class="line"><a name="l00263"></a><span class="lineno"> 263</span>&#160; </div>
<div class="line"><a name="l00264"></a><span class="lineno"> 264</span>&#160;Status EncryptionHandler::ProcessMediaSample(</div>
<div class="line"><a name="l00265"></a><span class="lineno"> 265</span>&#160; std::shared_ptr&lt;const MediaSample&gt; clear_sample) {</div>
<div class="line"><a name="l00266"></a><span class="lineno"> 266</span>&#160; DCHECK(clear_sample);</div>
<div class="line"><a name="l00267"></a><span class="lineno"> 267</span>&#160; </div>
<div class="line"><a name="l00268"></a><span class="lineno"> 268</span>&#160; <span class="comment">// Process the frame even if the frame is not encrypted as the next</span></div>
<div class="line"><a name="l00269"></a><span class="lineno"> 269</span>&#160; <span class="comment">// (encrypted) frame may be dependent on this clear frame.</span></div>
<div class="line"><a name="l00270"></a><span class="lineno"> 270</span>&#160; std::vector&lt;SubsampleEntry&gt; subsamples;</div>
<div class="line"><a name="l00271"></a><span class="lineno"> 271</span>&#160; RETURN_IF_ERROR(subsample_generator_-&gt;GenerateSubsamples(</div>
<div class="line"><a name="l00272"></a><span class="lineno"> 272</span>&#160; clear_sample-&gt;data(), clear_sample-&gt;data_size(), &amp;subsamples));</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">// Need to setup the encryptor for new segments even if this segment does not</span></div>
<div class="line"><a name="l00275"></a><span class="lineno"> 275</span>&#160; <span class="comment">// need to be encrypted, so we can signal encryption metadata earlier to</span></div>
<div class="line"><a name="l00276"></a><span class="lineno"> 276</span>&#160; <span class="comment">// allows clients to prefetch the keys.</span></div>
<div class="line"><a name="l00277"></a><span class="lineno"> 277</span>&#160; <span class="keywordflow">if</span> (check_new_crypto_period_) {</div>
<div class="line"><a name="l00278"></a><span class="lineno"> 278</span>&#160; <span class="comment">// |dts| can be negative, e.g. after EditList adjustments. Normalized to 0</span></div>
<div class="line"><a name="l00279"></a><span class="lineno"> 279</span>&#160; <span class="comment">// in that case.</span></div>
<div class="line"><a name="l00280"></a><span class="lineno"> 280</span>&#160; <span class="keyword">const</span> int64_t dts = std::max(clear_sample-&gt;dts(), <span class="keyword">static_cast&lt;</span>int64_t<span class="keyword">&gt;</span>(0));</div>
<div class="line"><a name="l00281"></a><span class="lineno"> 281</span>&#160; <span class="keyword">const</span> int64_t current_crypto_period_index = dts / crypto_period_duration_;</div>
<div class="line"><a name="l00282"></a><span class="lineno"> 282</span>&#160; <span class="keyword">const</span> uint32_t crypto_period_duration_in_seconds =</div>
<div class="line"><a name="l00283"></a><span class="lineno"> 283</span>&#160; <span class="keyword">static_cast&lt;</span>uint32_t<span class="keyword">&gt;</span>(encryption_params_.crypto_period_duration_in_seconds);</div>
<div class="line"><a name="l00284"></a><span class="lineno"> 284</span>&#160; <span class="keywordflow">if</span> (current_crypto_period_index != prev_crypto_period_index_) {</div>
<div class="line"><a name="l00285"></a><span class="lineno"> 285</span>&#160; EncryptionKey encryption_key;</div>
<div class="line"><a name="l00286"></a><span class="lineno"> 286</span>&#160; RETURN_IF_ERROR(key_source_-&gt;<a class="code" href="../../d1/d1f/classshaka_1_1media_1_1KeySource.html#aef67793f02b0cd34b57993fab9f789ae">GetCryptoPeriodKey</a>(</div>
<div class="line"><a name="l00287"></a><span class="lineno"> 287</span>&#160; current_crypto_period_index, crypto_period_duration_in_seconds,</div>
<div class="line"><a name="l00288"></a><span class="lineno"> 288</span>&#160; stream_label_, &amp;encryption_key));</div>
<div class="line"><a name="l00289"></a><span class="lineno"> 289</span>&#160; <span class="keywordflow">if</span> (!CreateEncryptor(encryption_key))</div>
<div class="line"><a name="l00290"></a><span class="lineno"> 290</span>&#160; <span class="keywordflow">return</span> Status(error::ENCRYPTION_FAILURE, <span class="stringliteral">&quot;Failed to create encryptor&quot;</span>);</div>
<div class="line"><a name="l00291"></a><span class="lineno"> 291</span>&#160; prev_crypto_period_index_ = current_crypto_period_index;</div>
<div class="line"><a name="l00292"></a><span class="lineno"> 292</span>&#160; }</div>
<div class="line"><a name="l00293"></a><span class="lineno"> 293</span>&#160; check_new_crypto_period_ = <span class="keyword">false</span>;</div>
<div class="line"><a name="l00294"></a><span class="lineno"> 294</span>&#160; }</div>
<div class="line"><a name="l00295"></a><span class="lineno"> 295</span>&#160; </div>
<div class="line"><a name="l00296"></a><span class="lineno"> 296</span>&#160; <span class="comment">// Since there is no encryption needed right now, send the clear copy</span></div>
<div class="line"><a name="l00297"></a><span class="lineno"> 297</span>&#160; <span class="comment">// downstream so we can save the costs of copying it.</span></div>
<div class="line"><a name="l00298"></a><span class="lineno"> 298</span>&#160; <span class="keywordflow">if</span> (remaining_clear_lead_ &gt; 0) {</div>
<div class="line"><a name="l00299"></a><span class="lineno"> 299</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#a9a74fead95bc16255e73908bbebbced9">DispatchMediaSample</a>(kStreamIndex, std::move(clear_sample));</div>
<div class="line"><a name="l00300"></a><span class="lineno"> 300</span>&#160; }</div>
<div class="line"><a name="l00301"></a><span class="lineno"> 301</span>&#160; </div>
<div class="line"><a name="l00302"></a><span class="lineno"> 302</span>&#160; std::shared_ptr&lt;uint8_t&gt; cipher_sample_data(</div>
<div class="line"><a name="l00303"></a><span class="lineno"> 303</span>&#160; <span class="keyword">new</span> uint8_t[clear_sample-&gt;data_size()], std::default_delete&lt;uint8_t[]&gt;());</div>
<div class="line"><a name="l00304"></a><span class="lineno"> 304</span>&#160; </div>
<div class="line"><a name="l00305"></a><span class="lineno"> 305</span>&#160; <span class="keyword">const</span> uint8_t* source = clear_sample-&gt;data();</div>
<div class="line"><a name="l00306"></a><span class="lineno"> 306</span>&#160; uint8_t* dest = cipher_sample_data.get();</div>
<div class="line"><a name="l00307"></a><span class="lineno"> 307</span>&#160; <span class="keywordflow">if</span> (!subsamples.empty()) {</div>
<div class="line"><a name="l00308"></a><span class="lineno"> 308</span>&#160; <span class="keywordtype">size_t</span> total_size = 0;</div>
<div class="line"><a name="l00309"></a><span class="lineno"> 309</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> SubsampleEntry&amp; subsample : subsamples) {</div>
<div class="line"><a name="l00310"></a><span class="lineno"> 310</span>&#160; <span class="keywordflow">if</span> (subsample.clear_bytes &gt; 0) {</div>
<div class="line"><a name="l00311"></a><span class="lineno"> 311</span>&#160; memcpy(dest, source, subsample.clear_bytes);</div>
<div class="line"><a name="l00312"></a><span class="lineno"> 312</span>&#160; source += subsample.clear_bytes;</div>
<div class="line"><a name="l00313"></a><span class="lineno"> 313</span>&#160; dest += subsample.clear_bytes;</div>
<div class="line"><a name="l00314"></a><span class="lineno"> 314</span>&#160; total_size += subsample.clear_bytes;</div>
<div class="line"><a name="l00315"></a><span class="lineno"> 315</span>&#160; }</div>
<div class="line"><a name="l00316"></a><span class="lineno"> 316</span>&#160; <span class="keywordflow">if</span> (subsample.cipher_bytes &gt; 0) {</div>
<div class="line"><a name="l00317"></a><span class="lineno"> 317</span>&#160; EncryptBytes(source, subsample.cipher_bytes, dest);</div>
<div class="line"><a name="l00318"></a><span class="lineno"> 318</span>&#160; source += subsample.cipher_bytes;</div>
<div class="line"><a name="l00319"></a><span class="lineno"> 319</span>&#160; dest += subsample.cipher_bytes;</div>
<div class="line"><a name="l00320"></a><span class="lineno"> 320</span>&#160; total_size += subsample.cipher_bytes;</div>
<div class="line"><a name="l00321"></a><span class="lineno"> 321</span>&#160; }</div>
<div class="line"><a name="l00322"></a><span class="lineno"> 322</span>&#160; }</div>
<div class="line"><a name="l00323"></a><span class="lineno"> 323</span>&#160; DCHECK_EQ(total_size, clear_sample-&gt;data_size());</div>
<div class="line"><a name="l00324"></a><span class="lineno"> 324</span>&#160; } <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00325"></a><span class="lineno"> 325</span>&#160; EncryptBytes(source, clear_sample-&gt;data_size(), dest);</div>
<div class="line"><a name="l00326"></a><span class="lineno"> 326</span>&#160; }</div>
<div class="line"><a name="l00327"></a><span class="lineno"> 327</span>&#160; </div>
<div class="line"><a name="l00328"></a><span class="lineno"> 328</span>&#160; std::shared_ptr&lt;MediaSample&gt; cipher_sample(clear_sample-&gt;Clone());</div>
<div class="line"><a name="l00329"></a><span class="lineno"> 329</span>&#160; cipher_sample-&gt;TransferData(std::move(cipher_sample_data),</div>
<div class="line"><a name="l00330"></a><span class="lineno"> 330</span>&#160; clear_sample-&gt;data_size());</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; <span class="comment">// Finish initializing the sample before sending it downstream. We must</span></div>
<div class="line"><a name="l00333"></a><span class="lineno"> 333</span>&#160; <span class="comment">// wait until now to finish the initialization as we will lose access to</span></div>
<div class="line"><a name="l00334"></a><span class="lineno"> 334</span>&#160; <span class="comment">// |decrypt_config| once we set it.</span></div>
<div class="line"><a name="l00335"></a><span class="lineno"> 335</span>&#160; cipher_sample-&gt;set_is_encrypted(<span class="keyword">true</span>);</div>
<div class="line"><a name="l00336"></a><span class="lineno"> 336</span>&#160; std::unique_ptr&lt;DecryptConfig&gt; decrypt_config(<span class="keyword">new</span> DecryptConfig(</div>
<div class="line"><a name="l00337"></a><span class="lineno"> 337</span>&#160; encryption_config_-&gt;key_id, encryptor_-&gt;iv(), subsamples,</div>
<div class="line"><a name="l00338"></a><span class="lineno"> 338</span>&#160; protection_scheme_, crypt_byte_block_, skip_byte_block_));</div>
<div class="line"><a name="l00339"></a><span class="lineno"> 339</span>&#160; cipher_sample-&gt;set_decrypt_config(std::move(decrypt_config));</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; encryptor_-&gt;UpdateIv();</div>
<div class="line"><a name="l00342"></a><span class="lineno"> 342</span>&#160; </div>
<div class="line"><a name="l00343"></a><span class="lineno"> 343</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#a9a74fead95bc16255e73908bbebbced9">DispatchMediaSample</a>(kStreamIndex, std::move(cipher_sample));</div>
<div class="line"><a name="l00344"></a><span class="lineno"> 344</span>&#160;}</div>
<div class="line"><a name="l00345"></a><span class="lineno"> 345</span>&#160; </div>
<div class="line"><a name="l00346"></a><span class="lineno"> 346</span>&#160;<span class="keywordtype">void</span> EncryptionHandler::SetupProtectionPattern(StreamType stream_type) {</div>
<div class="line"><a name="l00347"></a><span class="lineno"> 347</span>&#160; <span class="keywordflow">if</span> (stream_type == kStreamVideo &amp;&amp;</div>
<div class="line"><a name="l00348"></a><span class="lineno"> 348</span>&#160; IsPatternEncryptionScheme(protection_scheme_)) {</div>
<div class="line"><a name="l00349"></a><span class="lineno"> 349</span>&#160; crypt_byte_block_ = encryption_params_.<a class="code" href="../../dc/da0/structshaka_1_1EncryptionParams.html#a87b1deb1705f07c01efa69f14260e0af">crypt_byte_block</a>;</div>
<div class="line"><a name="l00350"></a><span class="lineno"> 350</span>&#160; skip_byte_block_ = encryption_params_.<a class="code" href="../../dc/da0/structshaka_1_1EncryptionParams.html#afa236ca5a091603c2bc6d28b1f84d816">skip_byte_block</a>;</div>
<div class="line"><a name="l00351"></a><span class="lineno"> 351</span>&#160; } <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00352"></a><span class="lineno"> 352</span>&#160; <span class="comment">// Audio stream in pattern encryption scheme does not use pattern; it uses</span></div>
<div class="line"><a name="l00353"></a><span class="lineno"> 353</span>&#160; <span class="comment">// whole-block full sample encryption instead. Non-pattern encryption does</span></div>
<div class="line"><a name="l00354"></a><span class="lineno"> 354</span>&#160; <span class="comment">// not have pattern.</span></div>
<div class="line"><a name="l00355"></a><span class="lineno"> 355</span>&#160; crypt_byte_block_ = 0u;</div>
<div class="line"><a name="l00356"></a><span class="lineno"> 356</span>&#160; skip_byte_block_ = 0u;</div>
<div class="line"><a name="l00357"></a><span class="lineno"> 357</span>&#160; }</div>
<div class="line"><a name="l00358"></a><span class="lineno"> 358</span>&#160;}</div>
<div class="line"><a name="l00359"></a><span class="lineno"> 359</span>&#160; </div>
<div class="line"><a name="l00360"></a><span class="lineno"> 360</span>&#160;<span class="keywordtype">bool</span> EncryptionHandler::CreateEncryptor(<span class="keyword">const</span> EncryptionKey&amp; encryption_key) {</div>
<div class="line"><a name="l00361"></a><span class="lineno"> 361</span>&#160; std::unique_ptr&lt;AesCryptor&gt; encryptor = encryptor_factory_-&gt;CreateEncryptor(</div>
<div class="line"><a name="l00362"></a><span class="lineno"> 362</span>&#160; protection_scheme_, crypt_byte_block_, skip_byte_block_, codec_,</div>
<div class="line"><a name="l00363"></a><span class="lineno"> 363</span>&#160; encryption_key.key, encryption_key.iv);</div>
<div class="line"><a name="l00364"></a><span class="lineno"> 364</span>&#160; <span class="keywordflow">if</span> (!encryptor)</div>
<div class="line"><a name="l00365"></a><span class="lineno"> 365</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line"><a name="l00366"></a><span class="lineno"> 366</span>&#160; encryptor_ = std::move(encryptor);</div>
<div class="line"><a name="l00367"></a><span class="lineno"> 367</span>&#160; </div>
<div class="line"><a name="l00368"></a><span class="lineno"> 368</span>&#160; encryption_config_.reset(<span class="keyword">new</span> EncryptionConfig);</div>
<div class="line"><a name="l00369"></a><span class="lineno"> 369</span>&#160; encryption_config_-&gt;protection_scheme = protection_scheme_;</div>
<div class="line"><a name="l00370"></a><span class="lineno"> 370</span>&#160; encryption_config_-&gt;crypt_byte_block = crypt_byte_block_;</div>
<div class="line"><a name="l00371"></a><span class="lineno"> 371</span>&#160; encryption_config_-&gt;skip_byte_block = skip_byte_block_;</div>
<div class="line"><a name="l00372"></a><span class="lineno"> 372</span>&#160; </div>
<div class="line"><a name="l00373"></a><span class="lineno"> 373</span>&#160; <span class="keyword">const</span> std::vector&lt;uint8_t&gt;&amp; iv = encryptor_-&gt;iv();</div>
<div class="line"><a name="l00374"></a><span class="lineno"> 374</span>&#160; <span class="keywordflow">if</span> (encryptor_-&gt;use_constant_iv()) {</div>
<div class="line"><a name="l00375"></a><span class="lineno"> 375</span>&#160; encryption_config_-&gt;per_sample_iv_size = 0;</div>
<div class="line"><a name="l00376"></a><span class="lineno"> 376</span>&#160; encryption_config_-&gt;constant_iv = iv;</div>
<div class="line"><a name="l00377"></a><span class="lineno"> 377</span>&#160; } <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00378"></a><span class="lineno"> 378</span>&#160; encryption_config_-&gt;per_sample_iv_size = <span class="keyword">static_cast&lt;</span>uint8_t<span class="keyword">&gt;</span>(iv.size());</div>
<div class="line"><a name="l00379"></a><span class="lineno"> 379</span>&#160; }</div>
<div class="line"><a name="l00380"></a><span class="lineno"> 380</span>&#160; </div>
<div class="line"><a name="l00381"></a><span class="lineno"> 381</span>&#160; encryption_config_-&gt;key_id = encryption_key.key_id;</div>
<div class="line"><a name="l00382"></a><span class="lineno"> 382</span>&#160; <span class="keyword">const</span> <span class="keyword">auto</span> status = FillProtectionSystemInfo(</div>
<div class="line"><a name="l00383"></a><span class="lineno"> 383</span>&#160; encryption_params_, encryption_key, encryption_config_.get());</div>
<div class="line"><a name="l00384"></a><span class="lineno"> 384</span>&#160; <span class="keywordflow">return</span> status.ok();</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;<span class="keywordtype">void</span> EncryptionHandler::EncryptBytes(<span class="keyword">const</span> uint8_t* source,</div>
<div class="line"><a name="l00388"></a><span class="lineno"> 388</span>&#160; <span class="keywordtype">size_t</span> source_size,</div>
<div class="line"><a name="l00389"></a><span class="lineno"> 389</span>&#160; uint8_t* dest) {</div>
<div class="line"><a name="l00390"></a><span class="lineno"> 390</span>&#160; DCHECK(source);</div>
<div class="line"><a name="l00391"></a><span class="lineno"> 391</span>&#160; DCHECK(dest);</div>
<div class="line"><a name="l00392"></a><span class="lineno"> 392</span>&#160; DCHECK(encryptor_);</div>
<div class="line"><a name="l00393"></a><span class="lineno"> 393</span>&#160; CHECK(encryptor_-&gt;Crypt(source, source_size, dest));</div>
<div class="line"><a name="l00394"></a><span class="lineno"> 394</span>&#160;}</div>
<div class="line"><a name="l00395"></a><span class="lineno"> 395</span>&#160; </div>
<div class="line"><a name="l00396"></a><span class="lineno"> 396</span>&#160;<span class="keywordtype">void</span> EncryptionHandler::InjectSubsampleGeneratorForTesting(</div>
<div class="line"><a name="l00397"></a><span class="lineno"> 397</span>&#160; std::unique_ptr&lt;SubsampleGenerator&gt; generator) {</div>
<div class="line"><a name="l00398"></a><span class="lineno"> 398</span>&#160; subsample_generator_ = std::move(generator);</div>
<div class="line"><a name="l00399"></a><span class="lineno"> 399</span>&#160;}</div>
<div class="line"><a name="l00400"></a><span class="lineno"> 400</span>&#160; </div>
<div class="line"><a name="l00401"></a><span class="lineno"> 401</span>&#160;<span class="keywordtype">void</span> EncryptionHandler::InjectEncryptorFactoryForTesting(</div>
<div class="line"><a name="l00402"></a><span class="lineno"> 402</span>&#160; std::unique_ptr&lt;AesEncryptorFactory&gt; encryptor_factory) {</div>
<div class="line"><a name="l00403"></a><span class="lineno"> 403</span>&#160; encryptor_factory_ = std::move(encryptor_factory);</div>
<div class="line"><a name="l00404"></a><span class="lineno"> 404</span>&#160;}</div>
<div class="line"><a name="l00405"></a><span class="lineno"> 405</span>&#160; </div>
<div class="line"><a name="l00406"></a><span class="lineno"> 406</span>&#160;} <span class="comment">// namespace media</span></div>
<div class="line"><a name="l00407"></a><span class="lineno"> 407</span>&#160;} <span class="comment">// namespace shaka</span></div>
</div><!-- fragment --></div><!-- contents -->
<div class="ttc" id="anamespaceshaka_html_aadc0cc211185374c4bf219da325673aca4a8a926ca6c8454f8249deec51b47e66"><div class="ttname"><a href="../../d8/daf/namespaceshaka.html#aadc0cc211185374c4bf219da325673aca4a8a926ca6c8454f8249deec51b47e66">shaka::ProtectionSystem::kCommon</a></div><div class="ttdeci">@ kCommon</div><div class="ttdoc">The common key system from EME: https://goo.gl/s8RIhr.</div></div>
<div class="ttc" id="astructshaka_1_1media_1_1SegmentInfo_html"><div class="ttname"><a href="../../d0/dc0/structshaka_1_1media_1_1SegmentInfo.html">shaka::media::SegmentInfo</a></div><div class="ttdef"><b>Definition:</b> <a href="../../d3/d93/media__handler_8h_source.html#l00055">media_handler.h:55</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1MediaHandler_html_a9a74fead95bc16255e73908bbebbced9"><div class="ttname"><a href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#a9a74fead95bc16255e73908bbebbced9">shaka::media::MediaHandler::DispatchMediaSample</a></div><div class="ttdeci">Status DispatchMediaSample(size_t stream_index, std::shared_ptr&lt; const MediaSample &gt; media_sample) const</div><div class="ttdoc">Dispatch the media sample to downstream handlers.</div><div class="ttdef"><b>Definition:</b> <a href="../../d3/d93/media__handler_8h_source.html#l00207">media_handler.h:207</a></div></div>
<div class="ttc" id="astructshaka_1_1EncryptionParams_html_a87b1deb1705f07c01efa69f14260e0af"><div class="ttname"><a href="../../dc/da0/structshaka_1_1EncryptionParams.html#a87b1deb1705f07c01efa69f14260e0af">shaka::EncryptionParams::crypt_byte_block</a></div><div class="ttdeci">uint8_t crypt_byte_block</div><div class="ttdef"><b>Definition:</b> <a href="../../dd/d58/crypto__params_8h_source.html#l00174">crypto_params.h:174</a></div></div>
<div class="ttc" id="anamespaceshaka_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="aclassshaka_1_1media_1_1MediaHandler_html_ad165375cd0a2074c5a740b42f847c499"><div class="ttname"><a href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#ad165375cd0a2074c5a740b42f847c499">shaka::media::MediaHandler::DispatchStreamInfo</a></div><div class="ttdeci">Status DispatchStreamInfo(size_t stream_index, std::shared_ptr&lt; const StreamInfo &gt; stream_info) const</div><div class="ttdoc">Dispatch the stream info to downstream handlers.</div><div class="ttdef"><b>Definition:</b> <a href="../../d3/d93/media__handler_8h_source.html#l00199">media_handler.h:199</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1KeySource_html_af56c833453d65297c4dc96c9d2f83e1a"><div class="ttname"><a href="../../d1/d1f/classshaka_1_1media_1_1KeySource.html#af56c833453d65297c4dc96c9d2f83e1a">shaka::media::KeySource::GetKey</a></div><div class="ttdeci">virtual Status GetKey(const std::string &amp;stream_label, EncryptionKey *key)=0</div></div>
<div class="ttc" id="aclassshaka_1_1Status_html"><div class="ttname"><a href="../../d2/d20/classshaka_1_1Status.html">shaka::Status</a></div><div class="ttdef"><b>Definition:</b> <a href="../../d1/d13/status_8h_source.html#l00110">status.h:110</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1KeySource_html_aef67793f02b0cd34b57993fab9f789ae"><div class="ttname"><a href="../../d1/d1f/classshaka_1_1media_1_1KeySource.html#aef67793f02b0cd34b57993fab9f789ae">shaka::media::KeySource::GetCryptoPeriodKey</a></div><div class="ttdeci">virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &amp;stream_label, EncryptionKey *key)=0</div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1StreamInfo_html_afdd9b2df8ae1c11bb033c44eaba5e38d"><div class="ttname"><a href="../../d5/db1/classshaka_1_1media_1_1StreamInfo.html#afdd9b2df8ae1c11bb033c44eaba5e38d">shaka::media::StreamInfo::Clone</a></div><div class="ttdeci">virtual std::unique_ptr&lt; StreamInfo &gt; Clone() const =0</div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1MediaHandler_html_afe98a4fd19eabe0fc78afc91959c34a6"><div class="ttname"><a href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#afe98a4fd19eabe0fc78afc91959c34a6">shaka::media::MediaHandler::Dispatch</a></div><div class="ttdeci">Status Dispatch(std::unique_ptr&lt; StreamData &gt; stream_data) const</div><div class="ttdef"><b>Definition:</b> <a href="../../d2/de9/media__handler_8cc_source.html#l00094">media_handler.cc:94</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1EncryptionHandler_html_a3f1808a4386081e5e1c9a798a1a69dd0"><div class="ttname"><a href="../../d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html#a3f1808a4386081e5e1c9a798a1a69dd0">shaka::media::EncryptionHandler::InitializeInternal</a></div><div class="ttdeci">Status InitializeInternal() override</div><div class="ttdef"><b>Definition:</b> <a href="../../d3/d9c/encryption__handler_8cc_source.html#l00175">encryption_handler.cc:175</a></div></div>
<div class="ttc" id="astructshaka_1_1EncryptionParams_html_a1ad46963dc926aa4b72813dccb3f6a45"><div class="ttname"><a href="../../dc/da0/structshaka_1_1EncryptionParams.html#a1ad46963dc926aa4b72813dccb3f6a45">shaka::EncryptionParams::clear_lead_in_seconds</a></div><div class="ttdeci">double clear_lead_in_seconds</div><div class="ttdoc">Clear lead duration in seconds.</div><div class="ttdef"><b>Definition:</b> <a href="../../dd/d58/crypto__params_8h_source.html#l00162">crypto_params.h:162</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1EncryptionHandler_html_a7887e6060eb572036674ecb9a7e045c4"><div class="ttname"><a href="../../d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html#a7887e6060eb572036674ecb9a7e045c4">shaka::media::EncryptionHandler::Process</a></div><div class="ttdeci">Status Process(std::unique_ptr&lt; StreamData &gt; stream_data) override</div><div class="ttdef"><b>Definition:</b> <a href="../../d3/d9c/encryption__handler_8cc_source.html#l00186">encryption_handler.cc:186</a></div></div>
<div class="ttc" id="astructshaka_1_1EncryptionParams_html_a7686a6aca6a7c3d077a5d7215c39fc51"><div class="ttname"><a href="../../dc/da0/structshaka_1_1EncryptionParams.html#a7686a6aca6a7c3d077a5d7215c39fc51">shaka::EncryptionParams::stream_label_func</a></div><div class="ttdeci">std::function&lt; std::string(const EncryptedStreamAttributes &amp;stream_attributes)&gt; stream_label_func</div><div class="ttdef"><b>Definition:</b> <a href="../../dd/d58/crypto__params_8h_source.html#l00216">crypto_params.h:216</a></div></div>
<div class="ttc" id="astructshaka_1_1EncryptionParams_html_afa236ca5a091603c2bc6d28b1f84d816"><div class="ttname"><a href="../../dc/da0/structshaka_1_1EncryptionParams.html#afa236ca5a091603c2bc6d28b1f84d816">shaka::EncryptionParams::skip_byte_block</a></div><div class="ttdeci">uint8_t skip_byte_block</div><div class="ttdef"><b>Definition:</b> <a href="../../dd/d58/crypto__params_8h_source.html#l00178">crypto_params.h:178</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1MediaHandler_html_a2acc1c84a61aee93229d493aa93308d5"><div class="ttname"><a href="../../da/dfd/classshaka_1_1media_1_1MediaHandler.html#a2acc1c84a61aee93229d493aa93308d5">shaka::media::MediaHandler::DispatchSegmentInfo</a></div><div class="ttdeci">Status DispatchSegmentInfo(size_t stream_index, std::shared_ptr&lt; const SegmentInfo &gt; segment_info) const</div><div class="ttdoc">Dispatch the segment info to downstream handlers.</div><div class="ttdef"><b>Definition:</b> <a href="../../d3/d93/media__handler_8h_source.html#l00224">media_handler.h:224</a></div></div>
<div class="ttc" id="aclassshaka_1_1media_1_1StreamInfo_html"><div class="ttname"><a href="../../d5/db1/classshaka_1_1media_1_1StreamInfo.html">shaka::media::StreamInfo</a></div><div class="ttdoc">Abstract class holds stream information.</div><div class="ttdef"><b>Definition:</b> <a href="../../d8/daa/stream__info_8h_source.html#l00065">stream_info.h:65</a></div></div>
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Tue Jun 22 2021 00:16:04 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.17
</small></address>
</body>
</html>