shaka-packager/docs/d1/df1/multi__segment__segmenter_8...

312 lines
41 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.6"/>
<title>DASH Media Packaging SDK: media/formats/mp4/multi_segment_segmenter.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/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</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 style="padding-left: 0.5em;">
<div id="projectname">DASH Media Packaging SDK
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.6 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="../../index.html"><span>Main&#160;Page</span></a></li>
<li><a href="../../namespaces.html"><span>Namespaces</span></a></li>
<li><a href="../../annotated.html"><span>Classes</span></a></li>
<li class="current"><a href="../../files.html"><span>Files</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="../../search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="../../search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<div id="navrow2" class="tabs2">
<ul class="tablist">
<li><a href="../../files.html"><span>File&#160;List</span></a></li>
</ul>
</div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Enumerator</a></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_39dc0668bd5a501998f94e8b4e546c71.html">media</a></li><li class="navelem"><a class="el" href="../../dir_65f7acfa8cf3a5f1edc11faa2428b914.html">formats</a></li><li class="navelem"><a class="el" href="../../dir_3e9291fd7a18fdecc763294cb2628910.html">mp4</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">multi_segment_segmenter.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/media/formats/mp4/multi_segment_segmenter.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 &quot;packager/base/strings/string_number_conversions.h&quot;</span></div>
<div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160;<span class="preprocessor">#include &quot;packager/base/strings/string_util.h&quot;</span></div>
<div class="line"><a name="l00011"></a><span class="lineno"> 11</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/buffer_writer.h&quot;</span></div>
<div class="line"><a name="l00012"></a><span class="lineno"> 12</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/media_stream.h&quot;</span></div>
<div class="line"><a name="l00013"></a><span class="lineno"> 13</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/muxer_options.h&quot;</span></div>
<div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160;<span class="preprocessor">#include &quot;packager/media/base/muxer_util.h&quot;</span></div>
<div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160;<span class="preprocessor">#include &quot;packager/media/event/muxer_listener.h&quot;</span></div>
<div class="line"><a name="l00016"></a><span class="lineno"> 16</span>&#160;<span class="preprocessor">#include &quot;packager/media/file/file.h&quot;</span></div>
<div class="line"><a name="l00017"></a><span class="lineno"> 17</span>&#160;<span class="preprocessor">#include &quot;packager/media/formats/mp4/box_definitions.h&quot;</span></div>
<div class="line"><a name="l00018"></a><span class="lineno"> 18</span>&#160;</div>
<div class="line"><a name="l00019"></a><span class="lineno"> 19</span>&#160;<span class="keyword">namespace </span>edash_packager {</div>
<div class="line"><a name="l00020"></a><span class="lineno"> 20</span>&#160;<span class="keyword">namespace </span>media {</div>
<div class="line"><a name="l00021"></a><span class="lineno"> 21</span>&#160;<span class="keyword">namespace </span>mp4 {</div>
<div class="line"><a name="l00022"></a><span class="lineno"> 22</span>&#160;</div>
<div class="line"><a name="l00023"></a><span class="lineno"> 23</span>&#160;MultiSegmentSegmenter::MultiSegmentSegmenter(<span class="keyword">const</span> MuxerOptions&amp; options,</div>
<div class="line"><a name="l00024"></a><span class="lineno"> 24</span>&#160; scoped_ptr&lt;FileType&gt; ftyp,</div>
<div class="line"><a name="l00025"></a><span class="lineno"> 25</span>&#160; scoped_ptr&lt;Movie&gt; moov)</div>
<div class="line"><a name="l00026"></a><span class="lineno"> 26</span>&#160; : Segmenter(options, ftyp.Pass(), moov.Pass()),</div>
<div class="line"><a name="l00027"></a><span class="lineno"> 27</span>&#160; styp_(new SegmentType),</div>
<div class="line"><a name="l00028"></a><span class="lineno"> 28</span>&#160; num_segments_(0) {</div>
<div class="line"><a name="l00029"></a><span class="lineno"> 29</span>&#160; <span class="comment">// Use the same brands for styp as ftyp.</span></div>
<div class="line"><a name="l00030"></a><span class="lineno"> 30</span>&#160; styp_-&gt;major_brand = Segmenter::ftyp()-&gt;major_brand;</div>
<div class="line"><a name="l00031"></a><span class="lineno"> 31</span>&#160; styp_-&gt;compatible_brands = Segmenter::ftyp()-&gt;compatible_brands;</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;</div>
<div class="line"><a name="l00034"></a><span class="lineno"> 34</span>&#160;MultiSegmentSegmenter::~MultiSegmentSegmenter() {}</div>
<div class="line"><a name="l00035"></a><span class="lineno"> 35</span>&#160;</div>
<div class="line"><a name="l00036"></a><span class="lineno"><a class="line" href="../../dc/d7a/classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html#a88be93ad6cce209ceaf086ab98009516"> 36</a></span>&#160;<span class="keywordtype">bool</span> <a class="code" href="../../dc/d7a/classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html#a88be93ad6cce209ceaf086ab98009516">MultiSegmentSegmenter::GetInitRange</a>(<span class="keywordtype">size_t</span>* offset, <span class="keywordtype">size_t</span>* size) {</div>
<div class="line"><a name="l00037"></a><span class="lineno"> 37</span>&#160; DLOG(INFO) &lt;&lt; <span class="stringliteral">&quot;MultiSegmentSegmenter outputs init segment: &quot;</span></div>
<div class="line"><a name="l00038"></a><span class="lineno"> 38</span>&#160; &lt;&lt; options().<a class="code" href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#addd401a47b287f3c18cbdc4bfa1a6963">output_file_name</a>;</div>
<div class="line"><a name="l00039"></a><span class="lineno"> 39</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</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;</div>
<div class="line"><a name="l00042"></a><span class="lineno"><a class="line" href="../../dc/d7a/classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html#a789a8b0449e433076dfc0c2344d32280"> 42</a></span>&#160;<span class="keywordtype">bool</span> <a class="code" href="../../dc/d7a/classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html#a789a8b0449e433076dfc0c2344d32280">MultiSegmentSegmenter::GetIndexRange</a>(<span class="keywordtype">size_t</span>* offset, <span class="keywordtype">size_t</span>* size) {</div>
<div class="line"><a name="l00043"></a><span class="lineno"> 43</span>&#160; DLOG(INFO) &lt;&lt; <span class="stringliteral">&quot;MultiSegmentSegmenter does not have index range.&quot;</span>;</div>
<div class="line"><a name="l00044"></a><span class="lineno"> 44</span>&#160; <span class="keywordflow">return</span> <span class="keyword">false</span>;</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;<a class="code" href="../../d2/d90/classedash__packager_1_1media_1_1Status.html">Status</a> MultiSegmentSegmenter::DoInitialize() {</div>
<div class="line"><a name="l00048"></a><span class="lineno"> 48</span>&#160; DCHECK(ftyp());</div>
<div class="line"><a name="l00049"></a><span class="lineno"> 49</span>&#160; DCHECK(moov());</div>
<div class="line"><a name="l00050"></a><span class="lineno"> 50</span>&#160; <span class="comment">// Generate the output file with init segment.</span></div>
<div class="line"><a name="l00051"></a><span class="lineno"> 51</span>&#160; <a class="code" href="../../de/d19/classedash__packager_1_1media_1_1File.html">File</a>* file = <a class="code" href="../../de/d19/classedash__packager_1_1media_1_1File.html#a0933ccd7df76fcf8fbcfe12c15dbf6c5">File::Open</a>(options().output_file_name.c_str(), <span class="stringliteral">&quot;w&quot;</span>);</div>
<div class="line"><a name="l00052"></a><span class="lineno"> 52</span>&#160; <span class="keywordflow">if</span> (file == NULL) {</div>
<div class="line"><a name="l00053"></a><span class="lineno"> 53</span>&#160; <span class="keywordflow">return</span> <a class="code" href="../../d2/d90/classedash__packager_1_1media_1_1Status.html">Status</a>(error::FILE_FAILURE,</div>
<div class="line"><a name="l00054"></a><span class="lineno"> 54</span>&#160; <span class="stringliteral">&quot;Cannot open file for write &quot;</span> + options().output_file_name);</div>
<div class="line"><a name="l00055"></a><span class="lineno"> 55</span>&#160; }</div>
<div class="line"><a name="l00056"></a><span class="lineno"> 56</span>&#160; scoped_ptr&lt;BufferWriter&gt; buffer(<span class="keyword">new</span> <a class="code" href="../../df/dde/classedash__packager_1_1media_1_1BufferWriter.html">BufferWriter</a>);</div>
<div class="line"><a name="l00057"></a><span class="lineno"> 57</span>&#160; ftyp()-&gt;<a class="code" href="../../d7/d8a/structedash__packager_1_1media_1_1mp4_1_1Box.html#aa7a756828b5514fcd3eaf16d86c413c0">Write</a>(buffer.get());</div>
<div class="line"><a name="l00058"></a><span class="lineno"> 58</span>&#160; moov()-&gt;<a class="code" href="../../d7/d8a/structedash__packager_1_1media_1_1mp4_1_1Box.html#aa7a756828b5514fcd3eaf16d86c413c0">Write</a>(buffer.get());</div>
<div class="line"><a name="l00059"></a><span class="lineno"> 59</span>&#160; <a class="code" href="../../d2/d90/classedash__packager_1_1media_1_1Status.html">Status</a> status = buffer-&gt;WriteToFile(file);</div>
<div class="line"><a name="l00060"></a><span class="lineno"> 60</span>&#160; <span class="keywordflow">if</span> (!file-&gt;<a class="code" href="../../de/d19/classedash__packager_1_1media_1_1File.html#a42290da768cd34316d2f4c5fc3976b38">Close</a>()) {</div>
<div class="line"><a name="l00061"></a><span class="lineno"> 61</span>&#160; LOG(WARNING) &lt;&lt; <span class="stringliteral">&quot;Failed to close the file properly: &quot;</span></div>
<div class="line"><a name="l00062"></a><span class="lineno"> 62</span>&#160; &lt;&lt; options().<a class="code" href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#addd401a47b287f3c18cbdc4bfa1a6963">output_file_name</a>;</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> status;</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;Status MultiSegmentSegmenter::DoFinalize() {</div>
<div class="line"><a name="l00068"></a><span class="lineno"> 68</span>&#160; <a class="code" href="../../dc/de1/classedash__packager_1_1media_1_1mp4_1_1Segmenter.html#a4e58a007d4daafe1b49a70d39e52e339">SetComplete</a>();</div>
<div class="line"><a name="l00069"></a><span class="lineno"> 69</span>&#160; <span class="keywordflow">return</span> Status::OK;</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;Status MultiSegmentSegmenter::DoFinalizeSegment() {</div>
<div class="line"><a name="l00073"></a><span class="lineno"> 73</span>&#160; DCHECK(sidx());</div>
<div class="line"><a name="l00074"></a><span class="lineno"> 74</span>&#160; <span class="comment">// earliest_presentation_time is the earliest presentation time of any</span></div>
<div class="line"><a name="l00075"></a><span class="lineno"> 75</span>&#160; <span class="comment">// access unit in the reference stream in the first subsegment.</span></div>
<div class="line"><a name="l00076"></a><span class="lineno"> 76</span>&#160; <span class="comment">// It will be re-calculated later when subsegments are finalized.</span></div>
<div class="line"><a name="l00077"></a><span class="lineno"> 77</span>&#160; sidx()-&gt;earliest_presentation_time =</div>
<div class="line"><a name="l00078"></a><span class="lineno"> 78</span>&#160; sidx()-&gt;references[0].earliest_presentation_time;</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; <span class="keywordflow">if</span> (options().num_subsegments_per_sidx &lt;= 0)</div>
<div class="line"><a name="l00081"></a><span class="lineno"> 81</span>&#160; <span class="keywordflow">return</span> WriteSegment();</div>
<div class="line"><a name="l00082"></a><span class="lineno"> 82</span>&#160;</div>
<div class="line"><a name="l00083"></a><span class="lineno"> 83</span>&#160; <span class="comment">// sidx() contains pre-generated segment references with one reference per</span></div>
<div class="line"><a name="l00084"></a><span class="lineno"> 84</span>&#160; <span class="comment">// fragment. Calculate |num_fragments_per_subsegment| and combine</span></div>
<div class="line"><a name="l00085"></a><span class="lineno"> 85</span>&#160; <span class="comment">// pre-generated references into final subsegment references.</span></div>
<div class="line"><a name="l00086"></a><span class="lineno"> 86</span>&#160; uint32_t num_fragments = sidx()-&gt;references.size();</div>
<div class="line"><a name="l00087"></a><span class="lineno"> 87</span>&#160; uint32_t num_fragments_per_subsegment =</div>
<div class="line"><a name="l00088"></a><span class="lineno"> 88</span>&#160; (num_fragments - 1) / options().<a class="code" href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#a93714f081569ea56ed626eb057c1761f">num_subsegments_per_sidx</a> + 1;</div>
<div class="line"><a name="l00089"></a><span class="lineno"> 89</span>&#160; <span class="keywordflow">if</span> (num_fragments_per_subsegment &lt;= 1)</div>
<div class="line"><a name="l00090"></a><span class="lineno"> 90</span>&#160; <span class="keywordflow">return</span> WriteSegment();</div>
<div class="line"><a name="l00091"></a><span class="lineno"> 91</span>&#160;</div>
<div class="line"><a name="l00092"></a><span class="lineno"> 92</span>&#160; uint32_t frag_index = 0;</div>
<div class="line"><a name="l00093"></a><span class="lineno"> 93</span>&#160; uint32_t subseg_index = 0;</div>
<div class="line"><a name="l00094"></a><span class="lineno"> 94</span>&#160; std::vector&lt;SegmentReference&gt;&amp; refs = sidx()-&gt;references;</div>
<div class="line"><a name="l00095"></a><span class="lineno"> 95</span>&#160; uint64_t first_sap_time =</div>
<div class="line"><a name="l00096"></a><span class="lineno"> 96</span>&#160; refs[0].sap_delta_time + refs[0].earliest_presentation_time;</div>
<div class="line"><a name="l00097"></a><span class="lineno"> 97</span>&#160; <span class="keywordflow">for</span> (uint32_t i = 1; i &lt; num_fragments; ++i) {</div>
<div class="line"><a name="l00098"></a><span class="lineno"> 98</span>&#160; refs[subseg_index].referenced_size += refs[i].referenced_size;</div>
<div class="line"><a name="l00099"></a><span class="lineno"> 99</span>&#160; refs[subseg_index].subsegment_duration += refs[i].subsegment_duration;</div>
<div class="line"><a name="l00100"></a><span class="lineno"> 100</span>&#160; refs[subseg_index].earliest_presentation_time =</div>
<div class="line"><a name="l00101"></a><span class="lineno"> 101</span>&#160; std::min(refs[subseg_index].earliest_presentation_time,</div>
<div class="line"><a name="l00102"></a><span class="lineno"> 102</span>&#160; refs[i].earliest_presentation_time);</div>
<div class="line"><a name="l00103"></a><span class="lineno"> 103</span>&#160; <span class="keywordflow">if</span> (refs[subseg_index].sap_type == SegmentReference::TypeUnknown &amp;&amp;</div>
<div class="line"><a name="l00104"></a><span class="lineno"> 104</span>&#160; refs[i].sap_type != SegmentReference::TypeUnknown) {</div>
<div class="line"><a name="l00105"></a><span class="lineno"> 105</span>&#160; refs[subseg_index].sap_type = refs[i].sap_type;</div>
<div class="line"><a name="l00106"></a><span class="lineno"> 106</span>&#160; first_sap_time =</div>
<div class="line"><a name="l00107"></a><span class="lineno"> 107</span>&#160; refs[i].sap_delta_time + refs[i].earliest_presentation_time;</div>
<div class="line"><a name="l00108"></a><span class="lineno"> 108</span>&#160; }</div>
<div class="line"><a name="l00109"></a><span class="lineno"> 109</span>&#160; <span class="keywordflow">if</span> (++frag_index &gt;= num_fragments_per_subsegment) {</div>
<div class="line"><a name="l00110"></a><span class="lineno"> 110</span>&#160; <span class="comment">// Calculate sap delta time w.r.t. sidx_-&gt;earliest_presentation_time.</span></div>
<div class="line"><a name="l00111"></a><span class="lineno"> 111</span>&#160; <span class="keywordflow">if</span> (refs[subseg_index].sap_type != SegmentReference::TypeUnknown) {</div>
<div class="line"><a name="l00112"></a><span class="lineno"> 112</span>&#160; refs[subseg_index].sap_delta_time =</div>
<div class="line"><a name="l00113"></a><span class="lineno"> 113</span>&#160; first_sap_time - refs[subseg_index].earliest_presentation_time;</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="keywordflow">if</span> (++i &gt;= num_fragments)</div>
<div class="line"><a name="l00116"></a><span class="lineno"> 116</span>&#160; <span class="keywordflow">break</span>;</div>
<div class="line"><a name="l00117"></a><span class="lineno"> 117</span>&#160; refs[++subseg_index] = refs[i];</div>
<div class="line"><a name="l00118"></a><span class="lineno"> 118</span>&#160; first_sap_time =</div>
<div class="line"><a name="l00119"></a><span class="lineno"> 119</span>&#160; refs[i].sap_delta_time + refs[i].earliest_presentation_time;</div>
<div class="line"><a name="l00120"></a><span class="lineno"> 120</span>&#160; frag_index = 1;</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; }</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; refs.resize(options().num_subsegments_per_sidx);</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; <span class="comment">// earliest_presentation_time is the earliest presentation time of any</span></div>
<div class="line"><a name="l00127"></a><span class="lineno"> 127</span>&#160; <span class="comment">// access unit in the reference stream in the first subsegment.</span></div>
<div class="line"><a name="l00128"></a><span class="lineno"> 128</span>&#160; sidx()-&gt;earliest_presentation_time = refs[0].earliest_presentation_time;</div>
<div class="line"><a name="l00129"></a><span class="lineno"> 129</span>&#160;</div>
<div class="line"><a name="l00130"></a><span class="lineno"> 130</span>&#160; <span class="keywordflow">return</span> WriteSegment();</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;</div>
<div class="line"><a name="l00133"></a><span class="lineno"> 133</span>&#160;Status MultiSegmentSegmenter::WriteSegment() {</div>
<div class="line"><a name="l00134"></a><span class="lineno"> 134</span>&#160; DCHECK(sidx());</div>
<div class="line"><a name="l00135"></a><span class="lineno"> 135</span>&#160; DCHECK(fragment_buffer());</div>
<div class="line"><a name="l00136"></a><span class="lineno"> 136</span>&#160; DCHECK(styp_);</div>
<div class="line"><a name="l00137"></a><span class="lineno"> 137</span>&#160;</div>
<div class="line"><a name="l00138"></a><span class="lineno"> 138</span>&#160; scoped_ptr&lt;BufferWriter&gt; buffer(<span class="keyword">new</span> BufferWriter());</div>
<div class="line"><a name="l00139"></a><span class="lineno"> 139</span>&#160; File* file;</div>
<div class="line"><a name="l00140"></a><span class="lineno"> 140</span>&#160; std::string file_name;</div>
<div class="line"><a name="l00141"></a><span class="lineno"> 141</span>&#160; <span class="keywordflow">if</span> (options().segment_template.empty()) {</div>
<div class="line"><a name="l00142"></a><span class="lineno"> 142</span>&#160; <span class="comment">// Append the segment to output file if segment template is not specified.</span></div>
<div class="line"><a name="l00143"></a><span class="lineno"> 143</span>&#160; file_name = options().<a class="code" href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#addd401a47b287f3c18cbdc4bfa1a6963">output_file_name</a>.c_str();</div>
<div class="line"><a name="l00144"></a><span class="lineno"> 144</span>&#160; file = <a class="code" href="../../de/d19/classedash__packager_1_1media_1_1File.html#a0933ccd7df76fcf8fbcfe12c15dbf6c5">File::Open</a>(file_name.c_str(), <span class="stringliteral">&quot;a&quot;</span>);</div>
<div class="line"><a name="l00145"></a><span class="lineno"> 145</span>&#160; <span class="keywordflow">if</span> (file == NULL) {</div>
<div class="line"><a name="l00146"></a><span class="lineno"> 146</span>&#160; <span class="keywordflow">return</span> Status(</div>
<div class="line"><a name="l00147"></a><span class="lineno"> 147</span>&#160; error::FILE_FAILURE,</div>
<div class="line"><a name="l00148"></a><span class="lineno"> 148</span>&#160; <span class="stringliteral">&quot;Cannot open file for append &quot;</span> + options().output_file_name);</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; } <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00151"></a><span class="lineno"> 151</span>&#160; file = <a class="code" href="../../de/d19/classedash__packager_1_1media_1_1File.html#a0933ccd7df76fcf8fbcfe12c15dbf6c5">File::Open</a>(GetSegmentName(options().segment_template,</div>
<div class="line"><a name="l00152"></a><span class="lineno"> 152</span>&#160; sidx()-&gt;earliest_presentation_time,</div>
<div class="line"><a name="l00153"></a><span class="lineno"> 153</span>&#160; num_segments_++,</div>
<div class="line"><a name="l00154"></a><span class="lineno"> 154</span>&#160; options().bandwidth).c_str(),</div>
<div class="line"><a name="l00155"></a><span class="lineno"> 155</span>&#160; <span class="stringliteral">&quot;w&quot;</span>);</div>
<div class="line"><a name="l00156"></a><span class="lineno"> 156</span>&#160; <span class="keywordflow">if</span> (file == NULL) {</div>
<div class="line"><a name="l00157"></a><span class="lineno"> 157</span>&#160; <span class="keywordflow">return</span> Status(error::FILE_FAILURE,</div>
<div class="line"><a name="l00158"></a><span class="lineno"> 158</span>&#160; <span class="stringliteral">&quot;Cannot open file for write &quot;</span> + file_name);</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; styp_-&gt;Write(buffer.get());</div>
<div class="line"><a name="l00161"></a><span class="lineno"> 161</span>&#160; }</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; <span class="comment">// If num_subsegments_per_sidx is negative, no SIDX box is generated.</span></div>
<div class="line"><a name="l00164"></a><span class="lineno"> 164</span>&#160; <span class="keywordflow">if</span> (options().<a class="code" href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#a93714f081569ea56ed626eb057c1761f">num_subsegments_per_sidx</a> &gt;= 0)</div>
<div class="line"><a name="l00165"></a><span class="lineno"> 165</span>&#160; sidx()-&gt;<a class="code" href="../../d7/d8a/structedash__packager_1_1media_1_1mp4_1_1Box.html#aa7a756828b5514fcd3eaf16d86c413c0">Write</a>(buffer.get());</div>
<div class="line"><a name="l00166"></a><span class="lineno"> 166</span>&#160;</div>
<div class="line"><a name="l00167"></a><span class="lineno"> 167</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> segment_size = buffer-&gt;Size() + fragment_buffer()-&gt;Size();</div>
<div class="line"><a name="l00168"></a><span class="lineno"> 168</span>&#160; DCHECK_NE(segment_size, 0u);</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; Status status = buffer-&gt;WriteToFile(file);</div>
<div class="line"><a name="l00171"></a><span class="lineno"> 171</span>&#160; <span class="keywordflow">if</span> (status.ok())</div>
<div class="line"><a name="l00172"></a><span class="lineno"> 172</span>&#160; status = fragment_buffer()-&gt;<a class="code" href="../../df/dde/classedash__packager_1_1media_1_1BufferWriter.html#aa83fe945386e5a75d3c377904fdddce2">WriteToFile</a>(file);</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; <span class="keywordflow">if</span> (!file-&gt;Close())</div>
<div class="line"><a name="l00175"></a><span class="lineno"> 175</span>&#160; LOG(WARNING) &lt;&lt; <span class="stringliteral">&quot;Failed to close the file properly: &quot;</span> &lt;&lt; file_name;</div>
<div class="line"><a name="l00176"></a><span class="lineno"> 176</span>&#160;</div>
<div class="line"><a name="l00177"></a><span class="lineno"> 177</span>&#160; <span class="keywordflow">if</span> (!status.ok())</div>
<div class="line"><a name="l00178"></a><span class="lineno"> 178</span>&#160; <span class="keywordflow">return</span> status;</div>
<div class="line"><a name="l00179"></a><span class="lineno"> 179</span>&#160;</div>
<div class="line"><a name="l00180"></a><span class="lineno"> 180</span>&#160; uint64_t segment_duration = 0;</div>
<div class="line"><a name="l00181"></a><span class="lineno"> 181</span>&#160; <span class="comment">// ISO/IEC 23009-1:2012: the value shall be identical to sum of the the</span></div>
<div class="line"><a name="l00182"></a><span class="lineno"> 182</span>&#160; <span class="comment">// values of all Subsegment_duration fields in the first sidx box.</span></div>
<div class="line"><a name="l00183"></a><span class="lineno"> 183</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0; i &lt; sidx()-&gt;references.size(); ++i)</div>
<div class="line"><a name="l00184"></a><span class="lineno"> 184</span>&#160; segment_duration += sidx()-&gt;references[i].subsegment_duration;</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"> 186</span>&#160; <a class="code" href="../../dc/de1/classedash__packager_1_1media_1_1mp4_1_1Segmenter.html#a287d51571c92704274550d9f1d246cf9">UpdateProgress</a>(segment_duration);</div>
<div class="line"><a name="l00187"></a><span class="lineno"> 187</span>&#160; <span class="keywordflow">if</span> (muxer_listener()) {</div>
<div class="line"><a name="l00188"></a><span class="lineno"> 188</span>&#160; muxer_listener()-&gt;<a class="code" href="../../df/de7/classedash__packager_1_1media_1_1MuxerListener.html#a5626ff553138db438c561db2ca0d05f2">OnSampleDurationReady</a>(<a class="code" href="../../dc/de1/classedash__packager_1_1media_1_1mp4_1_1Segmenter.html#ac2883a5eb0bd7abb50bc3968ac417901">sample_duration</a>());</div>
<div class="line"><a name="l00189"></a><span class="lineno"> 189</span>&#160; muxer_listener()-&gt;OnNewSegment(</div>
<div class="line"><a name="l00190"></a><span class="lineno"> 190</span>&#160; sidx()-&gt;earliest_presentation_time, segment_duration, segment_size);</div>
<div class="line"><a name="l00191"></a><span class="lineno"> 191</span>&#160; }</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="keywordflow">return</span> Status::OK;</div>
<div class="line"><a name="l00194"></a><span class="lineno"> 194</span>&#160;}</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="comment">// namespace mp4</span></div>
<div class="line"><a name="l00197"></a><span class="lineno"> 197</span>&#160;} <span class="comment">// namespace media</span></div>
<div class="line"><a name="l00198"></a><span class="lineno"> 198</span>&#160;} <span class="comment">// namespace edash_packager</span></div>
<div class="ttc" id="structedash__packager_1_1media_1_1MuxerOptions_html_addd401a47b287f3c18cbdc4bfa1a6963"><div class="ttname"><a href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#addd401a47b287f3c18cbdc4bfa1a6963">edash_packager::media::MuxerOptions::output_file_name</a></div><div class="ttdeci">std::string output_file_name</div><div class="ttdef"><b>Definition:</b> <a href="../../d0/d0e/muxer__options_8h_source.html#l00055">muxer_options.h:55</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1File_html_a42290da768cd34316d2f4c5fc3976b38"><div class="ttname"><a href="../../de/d19/classedash__packager_1_1media_1_1File.html#a42290da768cd34316d2f4c5fc3976b38">edash_packager::media::File::Close</a></div><div class="ttdeci">virtual bool Close()=0</div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1File_html"><div class="ttname"><a href="../../de/d19/classedash__packager_1_1media_1_1File.html">edash_packager::media::File</a></div><div class="ttdoc">Define an abstract file interface. </div><div class="ttdef"><b>Definition:</b> <a href="../../d2/d4d/file_8h_source.html#l00022">file.h:22</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1File_html_a0933ccd7df76fcf8fbcfe12c15dbf6c5"><div class="ttname"><a href="../../de/d19/classedash__packager_1_1media_1_1File.html#a0933ccd7df76fcf8fbcfe12c15dbf6c5">edash_packager::media::File::Open</a></div><div class="ttdeci">virtual bool Open()=0</div><div class="ttdoc">Internal open. Should not be used directly. </div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1Status_html"><div class="ttname"><a href="../../d2/d90/classedash__packager_1_1media_1_1Status.html">edash_packager::media::Status</a></div><div class="ttdef"><b>Definition:</b> <a href="../../d1/d13/status_8h_source.html#l00076">status.h:76</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter_html_a789a8b0449e433076dfc0c2344d32280"><div class="ttname"><a href="../../dc/d7a/classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html#a789a8b0449e433076dfc0c2344d32280">edash_packager::media::mp4::MultiSegmentSegmenter::GetIndexRange</a></div><div class="ttdeci">bool GetIndexRange(size_t *offset, size_t *size) override</div><div class="ttdef"><b>Definition:</b> <a href="../../d1/df1/multi__segment__segmenter_8cc_source.html#l00042">multi_segment_segmenter.cc:42</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1BufferWriter_html_aa83fe945386e5a75d3c377904fdddce2"><div class="ttname"><a href="../../df/dde/classedash__packager_1_1media_1_1BufferWriter.html#aa83fe945386e5a75d3c377904fdddce2">edash_packager::media::BufferWriter::WriteToFile</a></div><div class="ttdeci">Status WriteToFile(File *file)</div><div class="ttdef"><b>Definition:</b> <a href="../../dd/dd3/buffer__writer_8cc_source.html#l00065">buffer_writer.cc:65</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1mp4_1_1Segmenter_html_ac2883a5eb0bd7abb50bc3968ac417901"><div class="ttname"><a href="../../dc/de1/classedash__packager_1_1media_1_1mp4_1_1Segmenter.html#ac2883a5eb0bd7abb50bc3968ac417901">edash_packager::media::mp4::Segmenter::sample_duration</a></div><div class="ttdeci">uint32_t sample_duration() const </div><div class="ttdef"><b>Definition:</b> <a href="../../d4/dd4/segmenter_8h_source.html#l00101">segmenter.h:101</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1mp4_1_1Segmenter_html_a287d51571c92704274550d9f1d246cf9"><div class="ttname"><a href="../../dc/de1/classedash__packager_1_1media_1_1mp4_1_1Segmenter.html#a287d51571c92704274550d9f1d246cf9">edash_packager::media::mp4::Segmenter::UpdateProgress</a></div><div class="ttdeci">void UpdateProgress(uint64_t progress)</div><div class="ttdoc">Update segmentation progress using ProgressListener. </div><div class="ttdef"><b>Definition:</b> <a href="../../d1/d08/segmenter_8cc_source.html#l00333">segmenter.cc:333</a></div></div>
<div class="ttc" id="structedash__packager_1_1media_1_1MuxerOptions_html_a93714f081569ea56ed626eb057c1761f"><div class="ttname"><a href="../../de/d57/structedash__packager_1_1media_1_1MuxerOptions.html#a93714f081569ea56ed626eb057c1761f">edash_packager::media::MuxerOptions::num_subsegments_per_sidx</a></div><div class="ttdeci">int num_subsegments_per_sidx</div><div class="ttdef"><b>Definition:</b> <a href="../../d0/d0e/muxer__options_8h_source.html#l00050">muxer_options.h:50</a></div></div>
<div class="ttc" id="structedash__packager_1_1media_1_1mp4_1_1Box_html_aa7a756828b5514fcd3eaf16d86c413c0"><div class="ttname"><a href="../../d7/d8a/structedash__packager_1_1media_1_1mp4_1_1Box.html#aa7a756828b5514fcd3eaf16d86c413c0">edash_packager::media::mp4::Box::Write</a></div><div class="ttdeci">void Write(BufferWriter *writer)</div><div class="ttdef"><b>Definition:</b> <a href="../../d5/d4d/box_8cc_source.html#l00025">box.cc:25</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1mp4_1_1Segmenter_html_a4e58a007d4daafe1b49a70d39e52e339"><div class="ttname"><a href="../../dc/de1/classedash__packager_1_1media_1_1mp4_1_1Segmenter.html#a4e58a007d4daafe1b49a70d39e52e339">edash_packager::media::mp4::Segmenter::SetComplete</a></div><div class="ttdeci">void SetComplete()</div><div class="ttdoc">Set progress to 100%. </div><div class="ttdef"><b>Definition:</b> <a href="../../d1/d08/segmenter_8cc_source.html#l00349">segmenter.cc:349</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter_html_a88be93ad6cce209ceaf086ab98009516"><div class="ttname"><a href="../../dc/d7a/classedash__packager_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html#a88be93ad6cce209ceaf086ab98009516">edash_packager::media::mp4::MultiSegmentSegmenter::GetInitRange</a></div><div class="ttdeci">bool GetInitRange(size_t *offset, size_t *size) override</div><div class="ttdef"><b>Definition:</b> <a href="../../d1/df1/multi__segment__segmenter_8cc_source.html#l00036">multi_segment_segmenter.cc:36</a></div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1MuxerListener_html_a5626ff553138db438c561db2ca0d05f2"><div class="ttname"><a href="../../df/de7/classedash__packager_1_1media_1_1MuxerListener.html#a5626ff553138db438c561db2ca0d05f2">edash_packager::media::MuxerListener::OnSampleDurationReady</a></div><div class="ttdeci">virtual void OnSampleDurationReady(uint32_t sample_duration)=0</div></div>
<div class="ttc" id="classedash__packager_1_1media_1_1BufferWriter_html"><div class="ttname"><a href="../../df/dde/classedash__packager_1_1media_1_1BufferWriter.html">edash_packager::media::BufferWriter</a></div><div class="ttdef"><b>Definition:</b> <a href="../../dd/dd2/buffer__writer_8h_source.html#l00022">buffer_writer.h:22</a></div></div>
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Oct 22 2015 19:14:09 for DASH Media Packaging SDK by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.6
</small></address>
</body>
</html>