Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(921)

Side by Side Diff: LayoutTests/http/tests/media/media-source/mediasource-append-buffer.html

Issue 419673007: Adding more MSE tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Addressing CR comments Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <html> 2 <html>
3 <head> 3 <head>
4 <script src="/w3c/resources/testharness.js"></script> 4 <script src="/w3c/resources/testharness.js"></script>
5 <script src="/w3c/resources/testharnessreport.js"></script> 5 <script src="/w3c/resources/testharnessreport.js"></script>
6 <script src="mediasource-util.js"></script> 6 <script src="mediasource-util.js"></script>
7 <link rel='stylesheet' href='/w3c/resources/testharness.css'> 7 <link rel='stylesheet' href='/w3c/resources/testharness.css'>
8 </head> 8 </head>
9 <body> 9 <body>
10 <div id="log"></div> 10 <div id="log"></div>
11 <script> 11 <script>
12 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 12 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
13 { 13 {
14 test.failOnEvent(mediaElement, 'error'); 14 test.failOnEvent(mediaElement, 'error');
15 15
16 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 16 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
17 test.expectEvent(sourceBuffer, "update", "Append success."); 17 test.expectEvent(sourceBuffer, 'update', 'Append success.');
18 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 18 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
19 sourceBuffer.appendBuffer(mediaData); 19 sourceBuffer.appendBuffer(mediaData);
20 20
21 assert_true(sourceBuffer.updating, "updating attribute is true"); 21 assert_true(sourceBuffer.updating, 'updating attribute is true');
22 22
23 test.waitForExpectedEvents(function() 23 test.waitForExpectedEvents(function()
24 { 24 {
25 assert_false(sourceBuffer.updating, "updating attribute is fals e"); 25 assert_false(sourceBuffer.updating, 'updating attribute is fals e');
26 test.done(); 26 test.done();
27 }); 27 });
28 }, "Test SourceBuffer.appendBuffer() event dispatching."); 28 }, 'Test SourceBuffer.appendBuffer() event dispatching.');
29 29
30 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 30 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
31 { 31 {
32 test.failOnEvent(mediaElement, 'error'); 32 test.failOnEvent(mediaElement, 'error');
33 33
34 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 34 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
35 test.expectEvent(sourceBuffer, "update", "Append success."); 35 test.expectEvent(sourceBuffer, 'update', 'Append success.');
36 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 36 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
37 sourceBuffer.appendBuffer(mediaData); 37 sourceBuffer.appendBuffer(mediaData);
38 38
39 assert_true(sourceBuffer.updating, "updating attribute is true"); 39 assert_true(sourceBuffer.updating, 'updating attribute is true');
40 40
41 assert_throws("InvalidStateError", 41 assert_throws('InvalidStateError',
42 function() { sourceBuffer.appendBuffer(mediaData); }, 42 function() { sourceBuffer.appendBuffer(mediaData); },
43 "appendBuffer() throws an exception there is a pending append. "); 43 'appendBuffer() throws an exception there is a pending append. ');
44 44
45 assert_true(sourceBuffer.updating, "updating attribute is true"); 45 assert_true(sourceBuffer.updating, 'updating attribute is true');
46 46
47 test.waitForExpectedEvents(function() 47 test.waitForExpectedEvents(function()
48 { 48 {
49 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 49 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
50 test.done(); 50 test.done();
51 }); 51 });
52 }, "Test SourceBuffer.appendBuffer() call during a pending appendBuffe r()."); 52 }, 'Test SourceBuffer.appendBuffer() call during a pending appendBuffe r().');
53 53
54 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 54 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
55 { 55 {
56 test.failOnEvent(mediaElement, 'error'); 56 test.failOnEvent(mediaElement, 'error');
57 57
58 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 58 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
59 test.expectEvent(sourceBuffer, "abort", "Append aborted."); 59 test.expectEvent(sourceBuffer, 'abort', 'Append aborted.');
60 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 60 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
61 sourceBuffer.appendBuffer(mediaData); 61 sourceBuffer.appendBuffer(mediaData);
62 62
63 assert_true(sourceBuffer.updating, "updating attribute is true"); 63 assert_true(sourceBuffer.updating, 'updating attribute is true');
64 64
65 sourceBuffer.abort(); 65 sourceBuffer.abort();
66 66
67 assert_false(sourceBuffer.updating, "updating attribute is false") ; 67 assert_false(sourceBuffer.updating, 'updating attribute is false') ;
68 68
69 test.waitForExpectedEvents(function() 69 test.waitForExpectedEvents(function()
70 { 70 {
71 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 71 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
72 test.done(); 72 test.done();
73 }); 73 });
74 }, "Test SourceBuffer.abort() call during a pending appendBuffer()."); 74 }, 'Test SourceBuffer.abort() call during a pending appendBuffer().');
75 75
76 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 76 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
77 { 77 {
78 test.failOnEvent(mediaElement, 'error'); 78 test.failOnEvent(mediaElement, 'error');
79 79
80 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 80 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
81 test.expectEvent(sourceBuffer, "update", "Append success."); 81 test.expectEvent(sourceBuffer, 'update', 'Append success.');
82 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 82 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
83 sourceBuffer.appendBuffer(mediaData); 83 sourceBuffer.appendBuffer(mediaData);
84 assert_true(sourceBuffer.updating, "updating attribute is true"); 84 assert_true(sourceBuffer.updating, 'updating attribute is true');
85 85
86 test.waitForExpectedEvents(function() 86 test.waitForExpectedEvents(function()
87 { 87 {
88 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 88 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
89 89
90 test.expectEvent(mediaSource, "sourceended", "MediaSource sour ceended event"); 90 test.expectEvent(mediaSource, 'sourceended', 'MediaSource sour ceended event');
91 mediaSource.endOfStream(); 91 mediaSource.endOfStream();
92 assert_equals(mediaSource.readyState, "ended", "MediaSource re adyState is 'ended'"); 92 assert_equals(mediaSource.readyState, 'ended', 'MediaSource re adyState is "ended"');
93 }); 93 });
94 94
95 test.waitForExpectedEvents(function() 95 test.waitForExpectedEvents(function()
96 { 96 {
97 assert_equals(mediaSource.readyState, "ended", "MediaSource re adyState is 'ended'"); 97 assert_equals(mediaSource.readyState, 'ended', 'MediaSource re adyState is "ended"');
98 98
99 test.expectEvent(mediaSource, "sourceopen", "MediaSource sourc eopen event"); 99 test.expectEvent(mediaSource, 'sourceopen', 'MediaSource sourc eopen event');
100 test.expectEvent(sourceBuffer, "updatestart", "Append started. "); 100 test.expectEvent(sourceBuffer, 'updatestart', 'Append started. ');
101 test.expectEvent(sourceBuffer, "update", "Append success."); 101 test.expectEvent(sourceBuffer, 'update', 'Append success.');
102 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 102 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
103 sourceBuffer.appendBuffer(mediaData); 103 sourceBuffer.appendBuffer(mediaData);
104 104
105 assert_equals(mediaSource.readyState, "open", "MediaSource rea dyState is 'open'"); 105 assert_equals(mediaSource.readyState, 'open', 'MediaSource rea dyState is "open"');
106 assert_true(sourceBuffer.updating, "updating attribute is true "); 106 assert_true(sourceBuffer.updating, 'updating attribute is true ');
107 }); 107 });
108 108
109 test.waitForExpectedEvents(function() 109 test.waitForExpectedEvents(function()
110 { 110 {
111 assert_equals(mediaSource.readyState, "open", "MediaSource rea dyState is 'open'"); 111 assert_equals(mediaSource.readyState, 'open', 'MediaSource rea dyState is "open"');
112 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 112 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
113 test.done(); 113 test.done();
114 }); 114 });
115 }, "Test SourceBuffer.appendBuffer() triggering an 'ended' to 'open' t ransition."); 115 }, 'Test SourceBuffer.appendBuffer() triggering an "ended" to "open" t ransition.');
116 116
117 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 117 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
118 { 118 {
119 test.failOnEvent(mediaElement, 'error'); 119 test.failOnEvent(mediaElement, 'error');
120 120
121 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 121 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
122 test.expectEvent(sourceBuffer, "update", "Append success."); 122 test.expectEvent(sourceBuffer, 'update', 'Append success.');
123 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 123 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
124 sourceBuffer.appendBuffer(mediaData); 124 sourceBuffer.appendBuffer(mediaData);
125 assert_true(sourceBuffer.updating, "updating attribute is true"); 125 assert_true(sourceBuffer.updating, 'updating attribute is true');
126 126
127 test.waitForExpectedEvents(function() 127 test.waitForExpectedEvents(function()
128 { 128 {
129 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 129 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
130 130
131 test.expectEvent(mediaSource, "sourceended", "MediaSource sour ceended event"); 131 test.expectEvent(mediaSource, 'sourceended', 'MediaSource sour ceended event');
132 mediaSource.endOfStream(); 132 mediaSource.endOfStream();
133 assert_equals(mediaSource.readyState, "ended", "MediaSource re adyState is 'ended'"); 133 assert_equals(mediaSource.readyState, 'ended', 'MediaSource re adyState is "ended"');
134 }); 134 });
135 135
136 test.waitForExpectedEvents(function() 136 test.waitForExpectedEvents(function()
137 { 137 {
138 assert_equals(mediaSource.readyState, "ended", "MediaSource re adyState is 'ended'"); 138 assert_equals(mediaSource.readyState, 'ended', 'MediaSource re adyState is "ended"');
139 139
140 test.expectEvent(mediaSource, "sourceopen", "MediaSource sourc eopen event"); 140 test.expectEvent(mediaSource, 'sourceopen', 'MediaSource sourc eopen event');
141 test.expectEvent(sourceBuffer, "updatestart", "Append started. "); 141 test.expectEvent(sourceBuffer, 'updatestart', 'Append started. ');
142 test.expectEvent(sourceBuffer, "update", "Append success."); 142 test.expectEvent(sourceBuffer, 'update', 'Append success.');
143 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 143 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
144 sourceBuffer.appendBuffer(new Uint8Array(0)); 144 sourceBuffer.appendBuffer(new Uint8Array(0));
145 145
146 assert_equals(mediaSource.readyState, "open", "MediaSource rea dyState is 'open'"); 146 assert_equals(mediaSource.readyState, 'open', 'MediaSource rea dyState is "open"');
147 assert_true(sourceBuffer.updating, "updating attribute is true "); 147 assert_true(sourceBuffer.updating, 'updating attribute is true ');
148 }); 148 });
149 149
150 test.waitForExpectedEvents(function() 150 test.waitForExpectedEvents(function()
151 { 151 {
152 assert_equals(mediaSource.readyState, "open", "MediaSource rea dyState is 'open'"); 152 assert_equals(mediaSource.readyState, 'open', 'MediaSource rea dyState is "open"');
153 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 153 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
154 test.done(); 154 test.done();
155 }); 155 });
156 }, "Test zero byte SourceBuffer.appendBuffer() call triggering an 'end ed' to 'open' transition."); 156 }, 'Test zero byte SourceBuffer.appendBuffer() call triggering an "end ed" to "open" transition.');
157 157
158 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 158 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
159 { 159 {
160 test.failOnEvent(mediaElement, 'error'); 160 test.failOnEvent(mediaElement, 'error');
161 161
162 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 162 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
163 test.expectEvent(sourceBuffer, "abort", "Append aborted."); 163 test.expectEvent(sourceBuffer, 'abort', 'Append aborted.');
164 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 164 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
165 sourceBuffer.appendBuffer(mediaData); 165 sourceBuffer.appendBuffer(mediaData);
166 166
167 assert_true(sourceBuffer.updating, "updating attribute is true"); 167 assert_true(sourceBuffer.updating, 'updating attribute is true');
168 168
169 test.expectEvent(mediaSource.activeSourceBuffers, "removesourcebuf fer", "activeSourceBuffers"); 169 test.expectEvent(mediaSource.activeSourceBuffers, 'removesourcebuf fer', 'activeSourceBuffers');
170 test.expectEvent(mediaSource.sourceBuffers, "removesourcebuffer", "sourceBuffers"); 170 test.expectEvent(mediaSource.sourceBuffers, 'removesourcebuffer', 'sourceBuffers');
171 mediaSource.removeSourceBuffer(sourceBuffer); 171 mediaSource.removeSourceBuffer(sourceBuffer);
172 172
173 assert_false(sourceBuffer.updating, "updating attribute is false") ; 173 assert_false(sourceBuffer.updating, 'updating attribute is false') ;
174 174
175 assert_throws("InvalidStateError", 175 assert_throws('InvalidStateError',
176 function() { sourceBuffer.appendBuffer(mediaData); }, 176 function() { sourceBuffer.appendBuffer(mediaData); },
177 "appendBuffer() throws an exception because it isn't attached to the mediaSource anymore."); 177 'appendBuffer() throws an exception because it isn\'t attached to the mediaSource anymore.');
178 178
179 test.waitForExpectedEvents(function() 179 test.waitForExpectedEvents(function()
180 { 180 {
181 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 181 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
182 test.done(); 182 test.done();
183 }); 183 });
184 }, "Test MediaSource.removeSourceBuffer() call during a pending append Buffer()."); 184 }, 'Test MediaSource.removeSourceBuffer() call during a pending append Buffer().');
185 185
186 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 186 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
187 { 187 {
188 test.failOnEvent(mediaElement, 'error'); 188 test.failOnEvent(mediaElement, 'error');
189 189
190 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 190 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
191 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 191 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
192 sourceBuffer.appendBuffer(mediaData); 192 sourceBuffer.appendBuffer(mediaData);
193 193
194 assert_true(sourceBuffer.updating, "updating attribute is true"); 194 assert_true(sourceBuffer.updating, 'updating attribute is true');
195 195
196 assert_throws("InvalidStateError", 196 assert_throws('InvalidStateError',
197 function() { mediaSource.duration = 1.0; }, 197 function() { mediaSource.duration = 1.0; },
198 "set duration throws an exception when updating attribute is t rue."); 198 'set duration throws an exception when updating attribute is t rue.');
199 199
200 test.waitForExpectedEvents(function() 200 test.waitForExpectedEvents(function()
201 { 201 {
202 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 202 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
203 test.done(); 203 test.done();
204 }); 204 });
205 }, "Test set MediaSource.duration during a pending appendBuffer() for one of its SourceBuffers."); 205 }, 'Test set MediaSource.duration during a pending appendBuffer() for one of its SourceBuffers.');
206 206
207 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 207 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
208 { 208 {
209 test.failOnEvent(mediaElement, "error"); 209 test.failOnEvent(mediaElement, 'error');
210 test.failOnEvent(mediaSource, "sourceended"); 210 test.failOnEvent(mediaSource, 'sourceended');
211 211
212 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 212 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
213 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 213 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
214 sourceBuffer.appendBuffer(mediaData); 214 sourceBuffer.appendBuffer(mediaData);
215 215
216 assert_true(sourceBuffer.updating, "updating attribute is true"); 216 assert_true(sourceBuffer.updating, 'updating attribute is true');
217 217
218 assert_throws("InvalidStateError", 218 assert_throws('InvalidStateError',
219 function() { mediaSource.endOfStream(); }, 219 function() { mediaSource.endOfStream(); },
220 "endOfStream() throws an exception when updating attribute is true."); 220 'endOfStream() throws an exception when updating attribute is true.');
221 221
222 assert_equals(mediaSource.readyState, "open"); 222 assert_equals(mediaSource.readyState, 'open');
223 223
224 test.waitForExpectedEvents(function() 224 test.waitForExpectedEvents(function()
225 { 225 {
226 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 226 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
227 assert_equals(mediaSource.readyState, "open"); 227 assert_equals(mediaSource.readyState, 'open');
228 test.done(); 228 test.done();
229 }); 229 });
230 }, "Test MediaSource.endOfStream() during a pending appendBuffer() for one of its SourceBuffers."); 230 }, 'Test MediaSource.endOfStream() during a pending appendBuffer() for one of its SourceBuffers.');
231 231
232 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 232 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
233 { 233 {
234 test.failOnEvent(mediaElement, 'error'); 234 test.failOnEvent(mediaElement, 'error');
235 235
236 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 236 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
237 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 237 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
238 sourceBuffer.appendBuffer(mediaData); 238 sourceBuffer.appendBuffer(mediaData);
239 239
240 assert_true(sourceBuffer.updating, "updating attribute is true"); 240 assert_true(sourceBuffer.updating, 'updating attribute is true');
241 241
242 assert_throws("InvalidStateError", 242 assert_throws('InvalidStateError',
243 function() { sourceBuffer.timestampOffset = 10.0; }, 243 function() { sourceBuffer.timestampOffset = 10.0; },
244 "set timestampOffset throws an exception when updating attribu te is true."); 244 'set timestampOffset throws an exception when updating attribu te is true.');
245 245
246 test.waitForExpectedEvents(function() 246 test.waitForExpectedEvents(function()
247 { 247 {
248 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 248 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
249 test.done(); 249 test.done();
250 }); 250 });
251 }, "Test set SourceBuffer.timestampOffset during a pending appendBuffe r()."); 251 }, 'Test set SourceBuffer.timestampOffset during a pending appendBuffe r().');
252 252
253 mediasource_test(function(test, mediaElement, mediaSource) 253 mediasource_test(function(test, mediaElement, mediaSource)
254 { 254 {
255 var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VID EO_ONLY_TYPE); 255 var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VID EO_ONLY_TYPE);
256 256
257 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 257 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
258 test.expectEvent(sourceBuffer, "update", "Append success."); 258 test.expectEvent(sourceBuffer, 'update', 'Append success.');
259 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 259 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
260 sourceBuffer.appendBuffer(new Uint8Array(0)); 260 sourceBuffer.appendBuffer(new Uint8Array(0));
261 261
262 assert_true(sourceBuffer.updating, "updating attribute is true"); 262 assert_true(sourceBuffer.updating, 'updating attribute is true');
263 263
264 test.waitForExpectedEvents(function() 264 test.waitForExpectedEvents(function()
265 { 265 {
266 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 266 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
267 test.done(); 267 test.done();
268 }); 268 });
269 }, "Test appending an empty ArrayBufferView."); 269 }, 'Test appending an empty ArrayBufferView.');
270 270
wolenetz 2014/07/29 22:33:21 nit: remove extra line
prabhur1 2014/07/30 19:56:22 Done.
prabhur1 2014/07/30 19:56:22 ah...I need to get better are spotting those extra
wolenetz 2014/07/30 22:34:02 I can share off-CR some tips for horizontal traili
271 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 271
272 { 272 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
273 test.failOnEvent(mediaElement, 'error'); 273 {
274 274 test.failOnEvent(mediaElement, 'error');
275 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 275
276 test.expectEvent(sourceBuffer, "update", "Append success."); 276 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
277 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 277 test.expectEvent(sourceBuffer, 'update', 'Append success.');
278 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
278 279
279 var arrayBufferView = new Uint8Array(mediaData); 280 var arrayBufferView = new Uint8Array(mediaData);
280 281
281 assert_equals(arrayBufferView.length, mediaData.length, "arrayBuff erView.length before transfer."); 282 assert_equals(arrayBufferView.length, mediaData.length, 'arrayBuff erView.length before transfer.');
282 283
283 // Send the buffer as in a message so it gets neutered. 284 // Send the buffer as in a message so it gets neutered.
284 window.postMessage( "test", "*", [arrayBufferView.buffer]); 285 window.postMessage( 'test', '*', [arrayBufferView.buffer]);
285 286
286 assert_equals(arrayBufferView.length, 0, "arrayBufferView.length a fter transfer."); 287 assert_equals(arrayBufferView.length, 0, 'arrayBufferView.length a fter transfer.');
287 288
288 sourceBuffer.appendBuffer(arrayBufferView); 289 sourceBuffer.appendBuffer(arrayBufferView);
289 290
290 assert_true(sourceBuffer.updating, "updating attribute is true"); 291 assert_true(sourceBuffer.updating, 'updating attribute is true');
291 292
292 test.waitForExpectedEvents(function() 293 test.waitForExpectedEvents(function()
293 { 294 {
294 assert_false(sourceBuffer.updating, "updating attribute is fals e"); 295 assert_false(sourceBuffer.updating, 'updating attribute is fals e');
295 test.done(); 296 test.done();
296 }); 297 });
297 }, "Test appending a neutered ArrayBufferView."); 298 }, 'Test appending a neutered ArrayBufferView.');
298 299
299 mediasource_test(function(test, mediaElement, mediaSource) 300 mediasource_test(function(test, mediaElement, mediaSource)
300 { 301 {
301 var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VID EO_ONLY_TYPE); 302 var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VID EO_ONLY_TYPE);
302 303
303 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 304 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
304 test.expectEvent(sourceBuffer, "update", "Append success."); 305 test.expectEvent(sourceBuffer, 'update', 'Append success.');
305 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 306 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
306 sourceBuffer.appendBuffer(new ArrayBuffer(0)); 307 sourceBuffer.appendBuffer(new ArrayBuffer(0));
307 308
308 assert_true(sourceBuffer.updating, "updating attribute is true"); 309 assert_true(sourceBuffer.updating, 'updating attribute is true');
309 310
310 test.waitForExpectedEvents(function() 311 test.waitForExpectedEvents(function()
311 { 312 {
312 assert_false(sourceBuffer.updating, "updating attribute is fal se"); 313 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
313 test.done(); 314 test.done();
314 }); 315 });
315 }, "Test appending an empty ArrayBuffer."); 316 }, 'Test appending an empty ArrayBuffer.');
316 317
317 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 318 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
318 { 319 {
319 test.failOnEvent(mediaElement, 'error'); 320 test.failOnEvent(mediaElement, 'error');
320 321
321 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 322 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
322 test.expectEvent(sourceBuffer, "update", "Append success."); 323 test.expectEvent(sourceBuffer, 'update', 'Append success.');
323 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 324 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
324 325
325 var arrayBuffer = mediaData.buffer.slice(); 326 var arrayBuffer = mediaData.buffer.slice();
326 327
327 assert_equals(arrayBuffer.byteLength, mediaData.buffer.byteLength, "arrayBuffer.byteLength before transfer."); 328 assert_equals(arrayBuffer.byteLength, mediaData.buffer.byteLength, 'arrayBuffer.byteLength before transfer.');
328 329
329 // Send the buffer as in a message so it gets neutered. 330 // Send the buffer as in a message so it gets neutered.
330 window.postMessage( "test", "*", [arrayBuffer]); 331 window.postMessage( 'test', '*', [arrayBuffer]);
331 332
332 assert_equals(arrayBuffer.byteLength, 0, "arrayBuffer.byteLength a fter transfer."); 333 assert_equals(arrayBuffer.byteLength, 0, 'arrayBuffer.byteLength a fter transfer.');
333 334
334 sourceBuffer.appendBuffer(arrayBuffer); 335 sourceBuffer.appendBuffer(arrayBuffer);
335 336
336 assert_true(sourceBuffer.updating, "updating attribute is true"); 337 assert_true(sourceBuffer.updating, 'updating attribute is true');
337 338
338 test.waitForExpectedEvents(function() 339 test.waitForExpectedEvents(function()
339 { 340 {
340 assert_false(sourceBuffer.updating, "updating attribute is fals e"); 341 assert_false(sourceBuffer.updating, 'updating attribute is fals e');
341 test.done(); 342 test.done();
342 }); 343 });
343 }, "Test appending a neutered ArrayBuffer."); 344 }, 'Test appending a neutered ArrayBuffer.');
344 345
346 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
347 {
348 var initSegment = MediaSourceUtil.extractSegmentData(mediaData, se gmentInfo.init);
349 var halfIndex = (initSegment.length + 1) / 2;
350 var partialInitSegment = initSegment.subarray(0, halfIndex);
351 var remainingInitSegment = initSegment.subarray(halfIndex);
352 var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, s egmentInfo.media[0]);
353
wolenetz 2014/07/29 22:33:22 nit: remove extra horizontal whitespace in this li
prabhur1 2014/07/30 19:56:22 Done.
354 test.expectEvent(sourceBuffer, 'updateend', 'partialInitSegment ap pend ended.');
355 sourceBuffer.appendBuffer(partialInitSegment);
356
357 test.waitForExpectedEvents(function()
358 {
359 assert_equals(mediaElement.readyState, mediaElement.HAVE_NOTHI NG);
360 assert_equals(mediaSource.duration, Number.NaN);;
wolenetz 2014/07/29 22:33:22 nit: remove trailing extra ;
prabhur1 2014/07/30 19:56:21 Done.
361 test.expectEvent(sourceBuffer, 'updateend', 'remainingInitSegm ent append ended.');
362 test.expectEvent(mediaElement, 'loadedmetadata', 'loadedmetada ta event received.');
363 sourceBuffer.appendBuffer(remainingInitSegment);
364 });
365
366 test.waitForExpectedEvents(function()
367 {
368 assert_equals(mediaElement.readyState, mediaElement.HAVE_METAD ATA);
369 assert_equals(mediaSource.duration, segmentInfo.durationInInit Segment);;
wolenetz 2014/07/29 22:33:22 nit: remove trailing extra ;
prabhur1 2014/07/30 19:56:22 Done.
370 test.expectEvent(sourceBuffer, 'updateend', 'mediaSegment appe nd ended.');
371 test.expectEvent(mediaElement, 'loadeddata', 'loadeddata fired .');
372 sourceBuffer.appendBuffer(mediaSegment);
373 });
374
375 test.waitForExpectedEvents(function()
376 {
377 assert_greater_than_equal(mediaElement.readyState, mediaElemen t.HAVE_CURRENT_DATA);
378 assert_equals(sourceBuffer.updating, false);
379 assert_not_equals(mediaSource.readyState, 'ended');
wolenetz 2014/07/29 22:33:22 nit: I'm not convinced this check needs to be this
prabhur1 2014/07/30 19:56:22 Done.
380 test.done();
381 });
382 }, 'Test appendBuffer with partial init segments.');
383
384 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
385 {
386 var initSegment = MediaSourceUtil.extractSegmentData(mediaData, se gmentInfo.init);
387 var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, s egmentInfo.media[0]);
388 var halfIndex = (mediaSegment.length + 1) / 2;
389 var partialMediaSegment = mediaSegment.subarray(0, halfIndex);
390 var remainingMediaSegment = mediaSegment.subarray(halfIndex);
391
392 test.expectEvent(sourceBuffer, 'updateend', 'InitSegment append en ded.');
393 test.expectEvent(mediaElement, 'loadedmetadata', 'loadedmetadata d one.');
394 sourceBuffer.appendBuffer(initSegment);
395
396 test.waitForExpectedEvents(function()
397 {
398 assert_equals(mediaElement.readyState, mediaElement.HAVE_METAD ATA);
399 assert_equals(mediaSource.duration, segmentInfo.durationInInit Segment);
400 test.expectEvent(sourceBuffer, 'updateend', 'partial media seg ment append ended.');
401 sourceBuffer.appendBuffer(partialMediaSegment);
402 });
403
404 test.waitForExpectedEvents(function()
405 {
406 test.expectEvent(sourceBuffer, 'updateend', 'mediaSegment appe nd ended.');
407 test.expectEvent(mediaElement, 'loadeddata', 'loadeddata fired .');
wolenetz 2014/07/29 22:33:22 loadeddata could occur earlier, so this looks like
prabhur1 2014/07/30 19:56:21 Done.
prabhur1 2014/07/30 19:56:22 As per our discussion keeping this test as it is.
408 sourceBuffer.appendBuffer(remainingMediaSegment);
409 });
410
411 test.waitForExpectedEvents(function()
412 {
413 assert_greater_than_equal(mediaElement.readyState, mediaElemen t.HAVE_CURRENT_DATA);
414 assert_not_equals(mediaSource.readyState, 'ended');
wolenetz 2014/07/29 22:33:22 nit: ditto: assert 'open' instead?
prabhur1 2014/07/30 19:56:21 Done.
415 assert_equals(sourceBuffer.updating, false);
416 test.done();
417 });
418 }, 'Test appendBuffer with partial media segments.');
419
345 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 420 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
346 { 421 {
347 var initSegment = MediaSourceUtil.extractSegmentData(mediaData, se gmentInfo.init); 422 var initSegment = MediaSourceUtil.extractSegmentData(mediaData, se gmentInfo.init);
348 var partialInitSegment = initSegment.subarray(0, initSegment.lengt h / 2); 423 var partialInitSegment = initSegment.subarray(0, initSegment.lengt h / 2);
349 var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, s egmentInfo.media[0]); 424 var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, s egmentInfo.media[0]);
350 425
351 test.expectEvent(sourceBuffer, "updateend", "partialInitSegment ap pend ended."); 426 test.expectEvent(sourceBuffer, 'updateend', 'partialInitSegment ap pend ended.');
352 sourceBuffer.appendBuffer(partialInitSegment); 427 sourceBuffer.appendBuffer(partialInitSegment);
353 428
354 test.waitForExpectedEvents(function() 429 test.waitForExpectedEvents(function()
355 { 430 {
356 // Call abort to reset the parser. 431 // Call abort to reset the parser.
357 sourceBuffer.abort(); 432 sourceBuffer.abort();
358 433
359 // Append the full intiialization segment. 434 // Append the full intiialization segment.
360 test.expectEvent(sourceBuffer, "updateend", "initSegment appen d ended."); 435 test.expectEvent(sourceBuffer, 'updateend', 'initSegment appen d ended.');
361 sourceBuffer.appendBuffer(initSegment); 436 sourceBuffer.appendBuffer(initSegment);
362 }); 437 });
363 438
364 test.waitForExpectedEvents(function() 439 test.waitForExpectedEvents(function()
365 { 440 {
366 test.expectEvent(sourceBuffer, "updateend", "mediaSegment appe nd ended."); 441 test.expectEvent(sourceBuffer, 'updateend', 'mediaSegment appe nd ended.');
367 test.expectEvent(mediaElement, "loadeddata", "loadeddata fired ."); 442 test.expectEvent(mediaElement, 'loadeddata', 'loadeddata fired .');
368 sourceBuffer.appendBuffer(mediaSegment); 443 sourceBuffer.appendBuffer(mediaSegment);
369 }); 444 });
370 445
371 test.waitForExpectedEvents(function() 446 test.waitForExpectedEvents(function()
372 { 447 {
373 test.done(); 448 test.done();
374 }); 449 });
375 }, "Test abort in the middle of an initialization segment."); 450 }, 'Test abort in the middle of an initialization segment.');
376 451
377 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 452 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
378 { 453 {
379 var initSegment = MediaSourceUtil.extractSegmentData(mediaData, se gmentInfo.init); 454 var initSegment = MediaSourceUtil.extractSegmentData(mediaData, se gmentInfo.init);
380 var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, s egmentInfo.media[0]); 455 var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, s egmentInfo.media[0]);
381 var partialMediaSegment = mediaSegment.subarray(0, 3 * mediaSegmen t.length / 4); 456 var partialMediaSegment = mediaSegment.subarray(0, 3 * mediaSegmen t.length / 4);
382 var partialBufferedRanges = null; 457 var partialBufferedRanges = null;
383 458
384 test.expectEvent(sourceBuffer, "updateend", "initSegment append en ded."); 459 test.expectEvent(sourceBuffer, 'updateend', 'initSegment append en ded.');
385 sourceBuffer.appendBuffer(initSegment); 460 sourceBuffer.appendBuffer(initSegment);
386 461
387 test.waitForExpectedEvents(function() 462 test.waitForExpectedEvents(function()
388 { 463 {
389 test.expectEvent(sourceBuffer, "updateend", "partialMediaSegme nt append ended."); 464 test.expectEvent(sourceBuffer, 'updateend', 'partialMediaSegme nt append ended.');
390 sourceBuffer.appendBuffer(partialMediaSegment); 465 sourceBuffer.appendBuffer(partialMediaSegment);
391 }); 466 });
392 467
393 test.waitForExpectedEvents(function() 468 test.waitForExpectedEvents(function()
394 { 469 {
395 // Call abort to reset the parser. 470 // Call abort to reset the parser.
396 sourceBuffer.abort(); 471 sourceBuffer.abort();
397 472
398 // Keep a copy of the buffered ranges before we append the who le media segment. 473 // Keep a copy of the buffered ranges before we append the who le media segment.
399 partialBufferedRanges = sourceBuffer.buffered; 474 partialBufferedRanges = sourceBuffer.buffered;
400 assert_equals(partialBufferedRanges.length, 1, "partialBuffere dRanges has 1 range"); 475 assert_equals(partialBufferedRanges.length, 1, 'partialBuffere dRanges has 1 range');
401 476
402 // Append the full media segment. 477 // Append the full media segment.
403 test.expectEvent(sourceBuffer, "updateend", "mediaSegment appe nd ended."); 478 test.expectEvent(sourceBuffer, 'updateend', 'mediaSegment appe nd ended.');
404 sourceBuffer.appendBuffer(mediaSegment); 479 sourceBuffer.appendBuffer(mediaSegment);
405 }); 480 });
406 481
407 test.waitForExpectedEvents(function() 482 test.waitForExpectedEvents(function()
408 { 483 {
409 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 484 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
410 485
411 assert_equals(sourceBuffer.buffered.length, 1, "sourceBuffer.b uffered has 1 range"); 486 assert_equals(sourceBuffer.buffered.length, 1, 'sourceBuffer.b uffered has 1 range');
412 assert_equals(sourceBuffer.buffered.length, partialBufferedRan ges.length, "sourceBuffer.buffered and partialBufferedRanges are the same length ."); 487 assert_equals(sourceBuffer.buffered.length, partialBufferedRan ges.length, 'sourceBuffer.buffered and partialBufferedRanges are the same length .');
413 assert_equals(sourceBuffer.buffered.start(0), partialBufferedR anges.start(0), "sourceBuffer.buffered and partialBufferedRanges start times mat ch."); 488 assert_equals(sourceBuffer.buffered.start(0), partialBufferedR anges.start(0), 'sourceBuffer.buffered and partialBufferedRanges start times mat ch.');
414 assert_greater_than(sourceBuffer.buffered.end(0), partialBuffe redRanges.end(0), "sourceBuffer.buffered has a higher end time than partialBuffe redRanges."); 489 assert_greater_than(sourceBuffer.buffered.end(0), partialBuffe redRanges.end(0), 'sourceBuffer.buffered has a higher end time than partialBuffe redRanges.');
415 test.done(); 490 test.done();
416 }); 491 });
417 }, "Test abort in the middle of a media segment."); 492 }, 'Test abort in the middle of a media segment.');
493
494 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
495 {
496 test.expectEvent(mediaSource.sourceBuffers, 'removesourcebuffer', 'SourceBuffer removed.');
497 mediaSource.removeSourceBuffer(sourceBuffer);
498 test.waitForExpectedEvents(function()
499 {
500 assert_throws('InvalidStateError',
501 function() { sourceBuffer.abort(); },
502 'sourceBuffer.abort() throws an exception for InvalidState Error.');
503
504 test.done();
505 });
506 }, 'Test abort after removing sourcebuffer.');
507
508 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
509 {
510 test.expectEvent(mediaSource, 'sourceended', 'source ended');
511
512 assert_equals(mediaSource.readyState, 'open', 'readyState is open. ');
513 mediaSource.endOfStream();
514
515 test.waitForExpectedEvents(function()
516 {
517 assert_equals(mediaSource.readyState, 'ended', 'readyState is ended.');
518 assert_throws('InvalidStateError',
519 function() { sourceBuffer.abort(); },
520 'sourceBuffer.abort() throws an exception for InvalidState Error.');
521
522 test.done();
523 });
524
525 }, 'Test abort after readyState is ended.');
wolenetz 2014/07/29 22:33:22 Some of these tests, like all the "test abort *",
prabhur1 2014/07/30 19:56:22 Added a P2 to the spreadsheet. Yes, we need to add
prabhur1 2014/07/30 19:56:22 Done.
418 526
527 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
528 {
529 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
530 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
531 sourceBuffer.appendWindowStart = 1;
532 sourceBuffer.appendWindowEnd = 100;
533 sourceBuffer.appendBuffer(mediaData);
534
535 test.waitForExpectedEvents(function()
536 {
537 assert_false(sourceBuffer.updating, 'updating attribute is fal se');
538 sourceBuffer.abort();
539 assert_equals(sourceBuffer.appendWindowStart, 0, 'appendWindow Start is reset to 0');
540 assert_equals(sourceBuffer.appendWindowEnd, Number.POSITIVE_IN FINITY,
541 'appendWindowEnd is reset to +INFINITY');
542 test.done();
543 });
544 }, 'Test abort after appendBuffer update ends.');
545
419 mediasource_test(function(test, mediaElement, mediaSource) 546 mediasource_test(function(test, mediaElement, mediaSource)
420 { 547 {
421 var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VID EO_ONLY_TYPE); 548 var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.VID EO_ONLY_TYPE);
422 549
423 test.expectEvent(sourceBuffer, "updatestart", "Append started."); 550 test.expectEvent(sourceBuffer, 'updatestart', 'Append started.');
424 test.expectEvent(sourceBuffer, "update", "Append success."); 551 test.expectEvent(sourceBuffer, 'update', 'Append success.');
425 test.expectEvent(sourceBuffer, "updateend", "Append ended."); 552 test.expectEvent(sourceBuffer, 'updateend', 'Append ended.');
426 553
427 assert_throws( { name: "TypeError"} , 554 assert_throws( { name: 'TypeError'} ,
428 function() { sourceBuffer.appendBuffer(null); }, 555 function() { sourceBuffer.appendBuffer(null); },
429 "appendBuffer(null) throws an exception."); 556 'appendBuffer(null) throws an exception.');
430 test.done(); 557 test.done();
431 }, "Test appending null."); 558 }, 'Test appending null.');
432 559
433 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) 560 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData)
434 { 561 {
435 mediaSource.removeSourceBuffer(sourceBuffer); 562 mediaSource.removeSourceBuffer(sourceBuffer);
436 563
437 assert_throws( { name: "InvalidStateError"} , 564 assert_throws( { name: 'InvalidStateError'} ,
438 function() { sourceBuffer.appendBuffer(mediaData); }, 565 function() { sourceBuffer.appendBuffer(mediaData); },
439 "appendBuffer() throws an exception when called after removeSo urceBuffer()."); 566 'appendBuffer() throws an exception when called after removeSo urceBuffer().');
440 test.done(); 567 test.done();
441 }, "Test appending after removeSourceBuffer()."); 568 }, 'Test appending after removeSourceBuffer().');
wolenetz 2014/07/29 22:33:22 nit: remove trailing whitespace
prabhur1 2014/07/30 19:56:22 Done.
442 </script> 569 </script>
443 </body> 570 </body>
444 </html> 571 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698