OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** @suppress {duplicate} */ | 7 /** @suppress {duplicate} */ |
8 var remoting = remoting || {}; | 8 var remoting = remoting || {}; |
9 | 9 |
10 /** | 10 /** |
11 * @param {HTMLMediaElement} videoTag <video> tag to render to. | 11 * @param {HTMLMediaElement} videoTag <video> tag to render to. |
12 * @constructor | 12 * @constructor |
13 */ | 13 */ |
14 remoting.MediaSourceRenderer = function(videoTag) { | 14 remoting.MediaSourceRenderer = function(videoTag) { |
15 /** @type {HTMLMediaElement} */ | 15 /** @type {HTMLMediaElement} */ |
16 this.video_ = videoTag; | 16 this.video_ = videoTag; |
17 | 17 |
18 /** @type {MediaSource} */ | 18 /** @type {MediaSource} */ |
19 this.mediaSource_ = null; | 19 this.mediaSource_ = null; |
20 | 20 |
21 /** @type {SourceBuffer} */ | 21 /** @type {SourceBuffer} */ |
22 this.sourceBuffer_ = null; | 22 this.sourceBuffer_ = null; |
23 | 23 |
24 /** @type {!Array.<ArrayBuffer>} Queue of pending buffers that haven't been | 24 /** @type {!Array.<ArrayBuffer>} Queue of pending buffers that haven't been |
25 * processed . */ | 25 * processed. A null element indicates that the SourceBuffer can be reset |
| 26 * because the following buffer contains a keyframe. */ |
26 this.buffers_ = []; | 27 this.buffers_ = []; |
27 } | 28 } |
28 | 29 |
29 /** | 30 /** |
30 * @param {string} format Format of the stream. | 31 * @param {string} format Format of the stream. |
31 */ | 32 */ |
32 remoting.MediaSourceRenderer.prototype.reset = function(format) { | 33 remoting.MediaSourceRenderer.prototype.reset = function(format) { |
33 // Create a new MediaSource instance. | 34 // Create a new MediaSource instance. |
34 this.sourceBuffer_ = null; | 35 this.sourceBuffer_ = null; |
35 this.mediaSource_ = new MediaSource(); | 36 this.mediaSource_ = new MediaSource(); |
(...skipping 25 matching lines...) Expand all Loading... |
61 'updateend', this.processPendingData_.bind(this)); | 62 'updateend', this.processPendingData_.bind(this)); |
62 this.processPendingData_(); | 63 this.processPendingData_(); |
63 } | 64 } |
64 | 65 |
65 /** | 66 /** |
66 * @private | 67 * @private |
67 */ | 68 */ |
68 remoting.MediaSourceRenderer.prototype.processPendingData_ = function() { | 69 remoting.MediaSourceRenderer.prototype.processPendingData_ = function() { |
69 if (this.sourceBuffer_) { | 70 if (this.sourceBuffer_) { |
70 while (this.buffers_.length > 0 && !this.sourceBuffer_.updating) { | 71 while (this.buffers_.length > 0 && !this.sourceBuffer_.updating) { |
71 // TODO(sergeyu): Figure out the way to determine when a frame is rendered | 72 var buffer = /** @type {ArrayBuffer} */ this.buffers_.shift(); |
72 // and use it to report performance statistics. | 73 if (buffer == null) { |
73 this.sourceBuffer_.appendBuffer( | 74 // Remove all data from the SourceBuffer. By default Chrome buffers up |
74 /** @type {ArrayBuffer} */(this.buffers_.shift())); | 75 // 150MB of data in SourceBuffer. We never need to seek the stream, so |
| 76 // it doesn't make sense to keep any of that data. |
| 77 if (this.sourceBuffer_.buffered.length > 0) { |
| 78 this.sourceBuffer_.remove( |
| 79 this.sourceBuffer_.buffered.start(0), |
| 80 this.sourceBuffer_.buffered.end( |
| 81 this.sourceBuffer_.buffered.length - 1)); |
| 82 } |
| 83 } else { |
| 84 // TODO(sergeyu): Figure out the way to determine when a frame is |
| 85 // rendered and use it to report performance statistics. |
| 86 this.sourceBuffer_.appendBuffer(buffer); |
| 87 } |
75 } | 88 } |
76 } | 89 } |
77 } | 90 } |
78 | 91 |
79 /** | 92 /** |
80 * @param {ArrayBuffer} data | 93 * @param {ArrayBuffer} data |
| 94 * @param {boolean} keyframe |
81 */ | 95 */ |
82 remoting.MediaSourceRenderer.prototype.onIncomingData = function(data) { | 96 remoting.MediaSourceRenderer.prototype.onIncomingData = |
| 97 function(data, keyframe) { |
| 98 if (keyframe) { |
| 99 // Queue SourceBuffer reset request. |
| 100 this.buffers_.push(null); |
| 101 } |
83 this.buffers_.push(data); | 102 this.buffers_.push(data); |
84 this.processPendingData_(); | 103 this.processPendingData_(); |
85 } | 104 } |
86 | 105 |
OLD | NEW |