5ddb2763037df0c43dc7d59a3f7964b213f63bac
[WebKit-https.git] / LayoutTests / imported / w3c / web-platform-tests / media-source / mediasource-remove.html
1 <!DOCTYPE html>
2 <!--  Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
3 <html>
4     <head>
5         <title>SourceBuffer.remove() test cases.</title>
6         <script src="/resources/testharness.js"></script>
7         <script src="/resources/testharnessreport.js"></script>
8         <script src="mediasource-util.js"></script>
9     </head>
10     <body>
11         <div id="log"></div>
12         <script>
13           mediasource_test(function(test, mediaElement, mediaSource)
14           {
15               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
16
17               assert_throws(new TypeError(), function()
18               {
19                   sourceBuffer.remove(-1, 2);
20               }, "remove");
21
22               test.done();
23           }, "Test remove with an negative start.");
24
25           mediasource_test(function(test, mediaElement, mediaSource)
26           {
27               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
28
29               [ undefined, NaN, Infinity, -Infinity ].forEach(function(item)
30               {
31                   assert_throws(new TypeError(), function()
32                   {
33                       sourceBuffer.remove(item, 2);
34                   }, "remove");
35               });
36
37               test.done();
38           }, "Test remove with non-finite start.");
39
40           mediasource_test(function(test, mediaElement, mediaSource)
41           {
42               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
43
44               mediaSource.duration = 10;
45
46               assert_throws(new TypeError(), function()
47               {
48                   sourceBuffer.remove(11, 12);
49               }, "remove");
50
51               test.done();
52           }, "Test remove with a start beyond the duration.");
53
54           mediasource_test(function(test, mediaElement, mediaSource)
55           {
56               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
57
58               mediaSource.duration = 10;
59
60               assert_throws(new TypeError(), function()
61               {
62                   sourceBuffer.remove(2, 1);
63               }, "remove");
64
65               test.done();
66           }, "Test remove with a start larger than the end.");
67
68           mediasource_test(function(test, mediaElement, mediaSource)
69           {
70               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
71
72               assert_throws(new TypeError(), function()
73               {
74                   sourceBuffer.remove(0, Number.NEGATIVE_INFINITY);
75               }, "remove");
76
77               test.done();
78           }, "Test remove with a NEGATIVE_INFINITY end.");
79
80           mediasource_test(function(test, mediaElement, mediaSource)
81           {
82               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
83
84               assert_throws(new TypeError(), function()
85               {
86                   sourceBuffer.remove(0, Number.NaN);
87               }, "remove");
88
89               test.done();
90           }, "Test remove with a NaN end.");
91
92           mediasource_test(function(test, mediaElement, mediaSource)
93           {
94               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
95
96               mediaSource.duration = 10;
97
98               mediaSource.removeSourceBuffer(sourceBuffer);
99
100               assert_throws("InvalidStateError", function()
101               {
102                   sourceBuffer.remove(1, 2);
103               }, "remove");
104
105               test.done();
106           }, "Test remove after SourceBuffer removed from mediaSource.");
107
108
109           mediasource_test(function(test, mediaElement, mediaSource)
110           {
111               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
112
113               mediaSource.duration = 10;
114
115               test.expectEvent(sourceBuffer, "updatestart");
116               test.expectEvent(sourceBuffer, "update");
117               test.expectEvent(sourceBuffer, "updateend");
118               sourceBuffer.remove(1, 2);
119
120               assert_true(sourceBuffer.updating, "updating");
121
122               assert_throws("InvalidStateError", function()
123               {
124                   sourceBuffer.remove(3, 4);
125               }, "remove");
126
127               test.waitForExpectedEvents(function()
128               {
129                   test.done();
130               });
131           }, "Test remove while update pending.");
132
133           mediasource_test(function(test, mediaElement, mediaSource)
134           {
135               var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_VIDEO_TYPE);
136
137               mediaSource.duration = 10;
138
139               test.expectEvent(sourceBuffer, "updatestart");
140               test.expectEvent(sourceBuffer, "update");
141               test.expectEvent(sourceBuffer, "updateend");
142               sourceBuffer.remove(1, 2);
143
144               assert_true(sourceBuffer.updating, "updating");
145
146               assert_throws("InvalidStateError", function()
147               {
148                   sourceBuffer.abort();
149               }, "abort");
150
151               assert_true(sourceBuffer.updating, "updating");
152
153               test.waitForExpectedEvents(function()
154               {
155                   test.done();
156               });
157           }, "Test aborting a remove operation.");
158
159           mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
160           {
161               sourceBuffer.appendBuffer(mediaData);
162
163               test.expectEvent(sourceBuffer, "updatestart");
164               test.expectEvent(sourceBuffer, "update");
165               test.expectEvent(sourceBuffer, "updateend");
166
167               test.waitForExpectedEvents(function()
168               {
169                   assert_less_than(mediaSource.duration, 10)
170
171                   mediaSource.duration = 10;
172
173                   sourceBuffer.remove(mediaSource.duration, mediaSource.duration + 2);
174
175                   assert_true(sourceBuffer.updating, "updating");
176                   test.expectEvent(sourceBuffer, "updatestart");
177                   test.expectEvent(sourceBuffer, "update");
178                   test.expectEvent(sourceBuffer, "updateend");
179               });
180
181               test.waitForExpectedEvents(function()
182               {
183                   test.done();
184               });
185
186           }, "Test remove with a start at the duration.");
187
188           mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
189           {
190               test.expectEvent(sourceBuffer, "updatestart");
191               test.expectEvent(sourceBuffer, "update");
192               test.expectEvent(sourceBuffer, "updateend");
193               sourceBuffer.appendBuffer(mediaData);
194
195               test.waitForExpectedEvents(function()
196               {
197                   mediaSource.endOfStream();
198
199                   assert_equals(mediaSource.readyState, "ended");
200
201                   test.expectEvent(sourceBuffer, "updatestart");
202                   test.expectEvent(sourceBuffer, "update");
203                   test.expectEvent(sourceBuffer, "updateend");
204                   sourceBuffer.remove(1, 2);
205
206                   assert_true(sourceBuffer.updating, "updating");
207                   assert_equals(mediaSource.readyState, "open");
208               });
209
210               test.waitForExpectedEvents(function()
211               {
212                   assert_false(sourceBuffer.updating, "updating");
213                   test.done();
214               });
215           }, "Test remove transitioning readyState from 'ended' to 'open'.");
216
217           function removeAppendedDataTests(callback, description)
218           {
219               mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
220               {
221                   test.expectEvent(sourceBuffer, "updatestart");
222                   test.expectEvent(sourceBuffer, "update");
223                   test.expectEvent(sourceBuffer, "updateend");
224                   sourceBuffer.appendBuffer(mediaData);
225
226                   test.waitForExpectedEvents(function()
227                   {
228                       mediaSource.endOfStream();
229                       assert_false(sourceBuffer.updating, "updating");
230
231                       var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3);
232                       var duration = mediaElement.duration.toFixed(3);
233                       var subType = MediaSourceUtil.getSubType(segmentInfo.type);
234
235                       assertBufferedEquals(sourceBuffer, "{ [" + start + ", " + duration + ") }", "Initial buffered range.");
236                       callback(test, mediaSource, sourceBuffer, duration, subType, segmentInfo);
237                   });
238               }, description);
239           };
240           function removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, start, end, expected)
241           {
242               test.expectEvent(sourceBuffer, "updatestart");
243               test.expectEvent(sourceBuffer, "update");
244               test.expectEvent(sourceBuffer, "updateend");
245               sourceBuffer.remove(start, end);
246
247               test.waitForExpectedEvents(function()
248               {
249                   mediaSource.endOfStream();
250                   assert_false(sourceBuffer.updating, "updating");
251
252                   assertBufferedEquals(sourceBuffer, expected, "Buffered ranges after remove().");
253                   test.done();
254               });
255           }
256
257           removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
258           {
259               removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 0, Number.POSITIVE_INFINITY, "{ }");
260           }, "Test removing all appended data.");
261
262           removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
263           {
264               var expectations = {
265                 webm: ("{ [3.187, " + duration + ") }"),
266                 mp4: ("{ [3.187, " + duration + ") }"),
267               };
268
269               // Note: Range doesn't start exactly at the end of the remove range because there isn't
270               // a keyframe there. The resulting range starts at the first keyframe >= the end time.
271               removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 0, 3, expectations[subType]);
272           }, "Test removing beginning of appended data.");
273
274           removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
275           {
276               var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3);
277               var expectations = {
278                 webm: ("{ [" + start + ", 1.012) [3.187, " + duration + ") }"),
279                 mp4: ("{ [" + start + ", 0.996) [3.187, " + duration + ") }"),
280               };
281
282               // Note: The first resulting range ends slightly after start because the removal algorithm only removes
283               // frames with a timestamp >= the start time. If a frame starts before and ends after the remove() start
284               // timestamp, then it stays in the buffer.
285               removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 1, 3, expectations[subType]);
286           }, "Test removing the middle of appended data.");
287
288           removeAppendedDataTests(function(test, mediaSource, sourceBuffer, duration, subType, segmentInfo)
289           {
290               var start = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea).toFixed(3);
291               var expectations = {
292                 webm: "{ [" + start + ", 1.029) }",
293                 mp4: "{ [" + start + ", 1.022) }",
294               };
295
296               removeAndCheckBufferedRanges(test, mediaSource, sourceBuffer, 1, Number.POSITIVE_INFINITY, expectations[subType]);
297           }, "Test removing the end of appended data.");
298         </script>
299     </body>
300 </html>