OLD | NEW |
---|---|
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 function mediasource_truncated_duration_seek_test(testFunction, descri ption, options) | 12 function mediasource_duration_below_currentTime_seek_test(testFunction , description, options) |
13 { | 13 { |
14 return mediasource_testafterdataloaded(function(test, mediaElement , mediaSource, segmentInfo, sourceBuffer, mediaData) | 14 return mediasource_testafterdataloaded(function(test, mediaElement , mediaSource, segmentInfo, sourceBuffer, mediaData) |
15 { | 15 { |
16 assert_greater_than(segmentInfo.duration, 2, 'Sufficient test media duration'); | 16 assert_greater_than(segmentInfo.duration, 2, 'Sufficient test media duration'); |
17 | 17 |
18 var fullDuration = segmentInfo.duration; | 18 var fullDuration = segmentInfo.duration; |
19 var seekTo = fullDuration / 2.0; | 19 var seekTo = fullDuration / 2.0; |
20 var truncatedDuration = seekTo / 2.0; | 20 var reducedDuration = seekTo / 2.0; |
21 | 21 |
22 mediaElement.play(); | 22 mediaElement.play(); |
23 | 23 |
24 // Append all the segments | 24 // Append all the segments |
25 test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); | 25 test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); |
26 test.expectEvent(mediaElement, 'playing', 'Playing triggered') ; | 26 test.expectEvent(mediaElement, 'playing', 'Playing triggered') ; |
27 sourceBuffer.appendBuffer(mediaData); | 27 sourceBuffer.appendBuffer(mediaData); |
28 | 28 |
29 test.waitForExpectedEvents(function() | 29 test.waitForExpectedEvents(function() |
30 { | 30 { |
31 assert_equals(mediaElement.duration, fullDuration, 'mediaE lement fullDuration'); | 31 assert_equals(mediaElement.duration, fullDuration, 'mediaE lement fullDuration'); |
32 assert_equals(mediaSource.duration, fullDuration, 'mediaSo urce fullDuration'); | 32 assert_equals(mediaSource.duration, fullDuration, 'mediaSo urce fullDuration'); |
33 | 33 |
34 test.expectEvent(mediaElement, 'seeking', 'seeking to seek To'); | 34 test.expectEvent(mediaElement, 'seeking', 'seeking to seek To'); |
35 test.expectEvent(mediaElement, 'timeupdate', 'timeupdate w hile seeking to seekTo'); | 35 test.expectEvent(mediaElement, 'timeupdate', 'timeupdate w hile seeking to seekTo'); |
36 test.expectEvent(mediaElement, 'seeked', 'seeked to seekTo '); | 36 test.expectEvent(mediaElement, 'seeked', 'seeked to seekTo '); |
37 mediaElement.currentTime = seekTo; | 37 mediaElement.currentTime = seekTo; |
38 assert_true(mediaElement.seeking, 'mediaElement.seeking (t o seekTo)'); | 38 assert_true(mediaElement.seeking, 'mediaElement.seeking (t o seekTo)'); |
39 }); | 39 }); |
40 | 40 |
41 test.waitForExpectedEvents(function() | 41 test.waitForExpectedEvents(function() |
42 { | 42 { |
43 assert_greater_than_equal(mediaElement.currentTime, seekTo , 'Playback time has reached seekTo'); | 43 assert_greater_than_equal(mediaElement.currentTime, seekTo , 'Playback time has reached seekTo'); |
44 assert_equals(mediaElement.duration, fullDuration, 'mediaE lement fullDuration after seekTo'); | 44 assert_equals(mediaElement.duration, fullDuration, 'mediaE lement fullDuration after seekTo'); |
45 assert_equals(mediaSource.duration, fullDuration, 'mediaSo urce fullDuration after seekTo'); | 45 assert_equals(mediaSource.duration, fullDuration, 'mediaSo urce fullDuration after seekTo'); |
46 assert_false(mediaElement.seeking, 'mediaElement.seeking a fter seeked to seekTo'); | 46 assert_false(mediaElement.seeking, 'mediaElement.seeking a fter seeked to seekTo'); |
47 | 47 |
48 test.expectEvent(mediaElement, 'seeking', 'Seeking to trun cated duration'); | 48 // Explicitly remove buffered media beyond the new reduced duration prior to reducing duration. |
49 mediaSource.duration = truncatedDuration; | 49 // Implicit removal of buffered media as part of duration reduction is disallowed as of |
50 assert_true(mediaElement.seeking, 'Seeking after setting t runcatedDuration'); | 50 // https://github.com/w3c/media-source/pull/65/ |
51 test.expectEvent(sourceBuffer, 'updateend'); | |
52 sourceBuffer.remove(reducedDuration, fullDuration); | |
53 assert_true(sourceBuffer.updating, 'sourceBuffer.updating during range removal'); | |
51 }); | 54 }); |
52 | 55 |
53 test.waitForExpectedEvents(function() | 56 test.waitForExpectedEvents(function() |
54 { | 57 { |
55 assert_equals(mediaElement.currentTime, truncatedDuration, | 58 assert_false(sourceBuffer.updating, 'sourceBuffer.updating after range removal'); |
56 'Playback time is truncatedDuration while se eking'); | 59 assert_greater_than_equal(mediaElement.currentTime, seekTo , |
57 assert_true(mediaElement.seeking, 'mediaElement.seeking wh ile seeking to truncatedDuration'); | 60 'Playback time is still at least seekTo after range removal'); |
58 assert_equals(mediaElement.duration, truncatedDuration, | 61 |
59 'mediaElement truncatedDuration during seek to it'); | 62 test.expectEvent(mediaElement, 'seeking', 'Seeking to redu ced duration'); |
60 assert_equals(mediaSource.duration, truncatedDuration, | 63 mediaSource.duration = reducedDuration; |
61 'mediaSource truncatedDuration during seek t o it'); | 64 assert_true(mediaElement.seeking, 'Seeking after setting r educedDuration'); |
65 }); | |
66 | |
67 test.waitForExpectedEvents(function() | |
68 { | |
69 assert_equals(mediaElement.currentTime, reducedDuration, | |
70 'Playback time is reducedDuration while seek ing'); | |
71 assert_true(mediaElement.seeking, 'mediaElement.seeking wh ile seeking to reducedDuration'); | |
72 assert_equals(mediaElement.duration, reducedDuration, | |
73 'mediaElement reducedDuration during seek to it'); | |
74 assert_equals(mediaSource.duration, reducedDuration, | |
75 'mediaSource reducedDuration during seek to it'); | |
62 | 76 |
63 // FIXME: Confirm 'waiting' and then 'stalled' fire here. See http://crbug.com/266592. | 77 // FIXME: Confirm 'waiting' and then 'stalled' fire here. See http://crbug.com/266592. |
64 | 78 |
65 testFunction(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData, | 79 testFunction(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData, |
66 truncatedDuration); | 80 reducedDuration); |
67 }); | 81 }); |
68 }, description, options); | 82 }, description, options); |
69 } | 83 } |
70 | 84 |
71 mediasource_truncated_duration_seek_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, | 85 mediasource_duration_below_currentTime_seek_test(function(test, mediaE lement, mediaSource, segmentInfo, |
72 mediaData, truncated Duration) | 86 sourceBuffer, mediaDa ta, reducedDuration) |
73 { | 87 { |
74 // Tests that duration truncation below current playback position | 88 // Tests that duration reduction below current playback position |
75 // starts seek to new duration. | 89 // starts seek to new duration. |
76 test.done(); | 90 test.done(); |
77 }, 'Test seek starts on duration truncation below currentTime'); | 91 }, 'Test seek starts on duration reduction below currentTime'); |
78 | 92 |
79 mediasource_truncated_duration_seek_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, | 93 mediasource_duration_below_currentTime_seek_test(function(test, mediaE lement, mediaSource, segmentInfo, |
80 mediaData, truncated Duration) | 94 sourceBuffer, mediaDa ta, reducedDuration) |
81 { | 95 { |
82 // The duration has been truncated at this point, and there is an | 96 // The duration has been reduced at this point, and there is an |
83 // outstanding seek pending. | 97 // outstanding seek pending. |
84 test.expectEvent(sourceBuffer, 'updateend', 'updateend after appen ding more data'); | 98 test.expectEvent(sourceBuffer, 'updateend', 'updateend after appen ding more data'); |
85 | 99 |
86 // FIXME: Confirm 'playing' fires here. See http://crbug.com/26659 2. | 100 // FIXME: Confirm 'playing' fires here. See http://crbug.com/26659 2. |
87 | 101 |
88 test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while fin ishing seek to truncatedDuration'); | 102 test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while fin ishing seek to reducedDuration'); |
89 test.expectEvent(mediaElement, 'seeked', 'seeked to truncatedDurat ion'); | 103 test.expectEvent(mediaElement, 'seeked', 'seeked to reducedDuratio n'); |
90 | 104 |
91 // Allow seek to complete by appending more data beginning at the | 105 // Allow seek to complete by appending more data beginning at the |
92 // truncated duration timestamp. | 106 // reduced duration timestamp. |
93 sourceBuffer.timestampOffset = truncatedDuration; | 107 sourceBuffer.timestampOffset = reducedDuration; |
94 sourceBuffer.appendBuffer(mediaData); | 108 sourceBuffer.appendBuffer(mediaData); |
95 | 109 |
96 test.waitForExpectedEvents(function() | 110 test.waitForExpectedEvents(function() |
97 { | 111 { |
98 assert_greater_than_equal(mediaElement.currentTime, truncatedD uration, | 112 assert_greater_than_equal(mediaElement.currentTime, reducedDur ation, |
99 'Playback time has reached truncated Duration'); | 113 'Playback time has reached reducedDu ration'); |
100 assert_approx_equals(mediaElement.duration, truncatedDuration + segmentInfo.duration, 0.05, | 114 assert_approx_equals(mediaElement.duration, reducedDuration + segmentInfo.duration, 0.05, |
101 'mediaElement duration increased by new a ppend'); | 115 'mediaElement duration increased by new a ppend'); |
102 assert_equals(mediaSource.duration, mediaElement.duration, | 116 assert_equals(mediaSource.duration, mediaElement.duration, |
103 'mediaSource duration increased by new append'); | 117 'mediaSource duration increased by new append'); |
104 assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to truncatedDuration'); | 118 assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to reducedDuration'); |
105 | 119 |
106 test.done(); | 120 test.done(); |
107 }); | 121 }); |
108 }, 'Test appendBuffer completes previous seek to truncated duration'); | 122 }, 'Test appendBuffer completes previous seek to reduced duration'); |
109 | 123 |
110 mediasource_truncated_duration_seek_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, | 124 mediasource_duration_below_currentTime_seek_test(function(test, mediaE lement, mediaSource, segmentInfo, |
111 mediaData, truncated Duration) | 125 sourceBuffer, mediaDa ta, reducedDuration) |
112 { | 126 { |
113 // The duration has been truncated at this point, and there is an | 127 // The duration has been reduced at this point, and there is an |
114 // outstanding seek pending. | 128 // outstanding seek pending. |
115 test.expectEvent(mediaSource, 'sourceended', 'endOfStream acknowle dged'); | 129 test.expectEvent(mediaSource, 'sourceended', 'endOfStream acknowle dged'); |
116 | 130 |
117 // FIXME: Investigate if 'playing' should fire here. See http://cr bug.com/266592. | 131 // FIXME: Investigate if 'playing' should fire here. See http://cr bug.com/266592. |
118 | 132 |
119 test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while fin ishing seek to truncatedDuration'); | 133 test.expectEvent(mediaElement, 'timeupdate', 'timeupdate while fin ishing seek to reducedDuration'); |
120 test.expectEvent(mediaElement, 'seeked', 'seeked to truncatedDurat ion'); | 134 test.expectEvent(mediaElement, 'seeked', 'seeked to reducedDuratio n'); |
121 | 135 |
122 // Call endOfStream() to complete the pending seek. | 136 // Call endOfStream() to complete the pending seek. |
123 mediaSource.endOfStream(); | 137 mediaSource.endOfStream(); |
124 | 138 |
125 test.waitForExpectedEvents(function() | 139 test.waitForExpectedEvents(function() |
126 { | 140 { |
127 assert_equals(mediaElement.currentTime, truncatedDuration, | 141 assert_equals(mediaElement.currentTime, reducedDuration, |
128 'Playback time has reached truncatedDuration'); | 142 'Playback time has reached reducedDuration'); |
129 assert_equals(mediaElement.duration, truncatedDuration, | 143 assert_equals(mediaElement.duration, reducedDuration, |
130 'mediaElement truncatedDuration after seek to it '); | 144 'mediaElement reducedDuration after seek to it') ; |
chcunningham
2016/06/30 20:27:42
nit: can you make these more readable sentences? i
wolenetz
2016/06/30 20:47:03
Done.
| |
131 assert_equals(mediaSource.duration, truncatedDuration, | 145 assert_equals(mediaSource.duration, reducedDuration, |
132 'mediaSource truncatedDuration after seek to it' ); | 146 'mediaSource reducedDuration after seek to it'); |
133 assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to truncatedDuration'); | 147 assert_false(mediaElement.seeking, 'mediaElement.seeking after seeked to reducedDuration'); |
134 | 148 |
135 test.done(); | 149 test.done(); |
136 }); | 150 }); |
137 }, 'Test endOfStream completes previous seek to truncated duration'); | 151 }, 'Test endOfStream completes previous seek to reduced duration'); |
138 | 152 |
139 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) | 153 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) |
140 { | 154 { |
141 assert_greater_than(segmentInfo.duration, 2, 'Sufficient test medi a duration'); | 155 assert_greater_than(segmentInfo.duration, 2, 'Sufficient test medi a duration'); |
142 | 156 |
143 var fullDuration = segmentInfo.duration; | 157 var fullDuration = segmentInfo.duration; |
144 var newDuration = 0.5; | 158 var newDuration = fullDuration * 2; |
145 | 159 |
146 var durationchangeEventCounter = 0; | 160 var durationchangeEventCounter = 0; |
147 var expectedDurationChangeEventCount = 1; | 161 var expectedDurationChangeEventCount = 1; |
148 var durationchangeEventHandler = test.step_func(function(event) | 162 var durationchangeEventHandler = test.step_func(function(event) |
149 { | 163 { |
150 assert_equals(mediaElement.duration, newDuration, 'mediaElemen t newDuration'); | 164 assert_equals(mediaElement.duration, newDuration, 'mediaElemen t newDuration'); |
151 assert_equals(mediaSource.duration, newDuration, 'mediaSource newDuration'); | 165 assert_equals(mediaSource.duration, newDuration, 'mediaSource newDuration'); |
152 durationchangeEventCounter++; | 166 durationchangeEventCounter++; |
153 }); | 167 }); |
154 | 168 |
155 mediaElement.play(); | 169 mediaElement.play(); |
156 | 170 |
157 // Append all the segments | 171 // Append all the segments |
158 test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); | 172 test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); |
159 test.expectEvent(mediaElement, 'playing', 'Playing triggered'); | 173 test.expectEvent(mediaElement, 'playing', 'Playing triggered'); |
160 sourceBuffer.appendBuffer(mediaData); | 174 sourceBuffer.appendBuffer(mediaData); |
161 | 175 |
162 test.waitForExpectedEvents(function() | 176 test.waitForExpectedEvents(function() |
163 { | 177 { |
164 assert_equals(mediaElement.duration, fullDuration, 'mediaEleme nt fullDuration'); | 178 assert_equals(mediaElement.duration, fullDuration, 'mediaEleme nt fullDuration'); |
165 assert_equals(mediaSource.duration, fullDuration, 'mediaSource fullDuration'); | 179 assert_equals(mediaSource.duration, fullDuration, 'mediaSource fullDuration'); |
166 assert_less_than(mediaElement.currentTime, newDuration / 2, 'm ediaElement currentTime'); | 180 assert_less_than(mediaElement.currentTime, newDuration / 2, 'm ediaElement currentTime'); |
167 | 181 |
168 // Media load also fires 'durationchange' event, so only start counting them now. | 182 // Media load also fires 'durationchange' event, so only start counting them now. |
169 mediaElement.addEventListener('durationchange', durationchange EventHandler); | 183 mediaElement.addEventListener('durationchange', durationchange EventHandler); |
170 | 184 |
171 // Truncate duration. This should result in one 'durationchang e' fired. | 185 // Increase duration. This should result in one 'durationchang e' fired. |
172 mediaSource.duration = newDuration; | 186 mediaSource.duration = newDuration; |
187 assert_false(sourceBuffer.updating, "sourceBuffer.updating"); | |
173 | 188 |
174 assert_true(sourceBuffer.updating, "sourceBuffer.updating"); | |
175 test.expectEvent(sourceBuffer, "updateend"); | |
176 }); | |
177 | |
178 test.waitForExpectedEvents(function() | |
179 { | |
180 // Set duration again to make sure it does not trigger another 'durationchange' event. | 189 // Set duration again to make sure it does not trigger another 'durationchange' event. |
181 mediaSource.duration = newDuration; | 190 mediaSource.duration = newDuration; |
182 | 191 |
183 assert_false(sourceBuffer.updating, "sourceBuffer.updating"); | 192 assert_false(sourceBuffer.updating, "sourceBuffer.updating"); |
184 | 193 |
185 // Mark endOfStream so that playback can reach 'ended' at the new duration. | 194 // Mark endOfStream so that playback can reach 'ended' at the new duration. |
186 test.expectEvent(mediaSource, 'sourceended', 'endOfStream ackn owledged'); | 195 test.expectEvent(mediaSource, 'sourceended', 'endOfStream ackn owledged'); |
187 mediaSource.endOfStream(); | 196 mediaSource.endOfStream(); |
188 | 197 |
189 // endOfStream can change duration downwards slightly. | 198 // endOfStream can change duration downwards slightly. |
190 // Allow for one more 'durationchange' event only in this case . | 199 // Allow for one more 'durationchange' event only in this case . |
191 var currentDuration = mediaSource.duration; | 200 var currentDuration = mediaSource.duration; |
192 if (currentDuration != newDuration) { | 201 if (currentDuration != newDuration) { |
193 assert_true(currentDuration > 0 && currentDuration < newDu ration, 'adjusted duration'); | 202 assert_true(currentDuration > 0 && currentDuration < newDu ration, 'adjusted duration'); |
194 newDuration = currentDuration; | 203 newDuration = currentDuration; |
195 ++expectedDurationChangeEventCount; | 204 ++expectedDurationChangeEventCount; |
196 } | 205 } |
206 }); | |
197 | 207 |
198 // Allow media to play to end while counting 'durationchange' events. | 208 test.waitForExpectedEvents(function() |
199 test.expectEvent(mediaElement, 'ended', 'Playback ended'); | 209 { |
200 test.waitForExpectedEvents(function() | 210 // Allow any remaining queued durationchange to fire, while co unting 'durationchange' them. |
211 test.step_timeout(test.step_func(function() | |
201 { | 212 { |
202 mediaElement.removeEventListener('durationchange', duratio nchangeEventHandler); | 213 mediaElement.removeEventListener('durationchange', duratio nchangeEventHandler); |
203 assert_equals(durationchangeEventCounter, expectedDuration ChangeEventCount, 'durationchanges'); | 214 assert_equals(durationchangeEventCounter, expectedDuration ChangeEventCount, 'durationchanges'); |
204 test.done(); | 215 test.done(); |
205 }); | 216 }), 0); |
206 }); | 217 }); |
207 }, 'Test setting same duration multiple times does not fire duplicate durationchange', {timeout: 2500}); | 218 }, 'Test setting same duration multiple times does not fire duplicate durationchange', {timeout: 2500}); |
208 | 219 |
220 mediasource_testafterdataloaded(function(test, mediaElement, mediaSour ce, segmentInfo, sourceBuffer, mediaData) | |
221 { | |
222 assert_greater_than(segmentInfo.duration, 2, 'Sufficient test medi a duration'); | |
223 | |
224 var fullDuration = segmentInfo.duration; | |
225 | |
226 // Append all the segments | |
227 test.expectEvent(sourceBuffer, 'updateend', 'sourceBuffer'); | |
228 sourceBuffer.appendBuffer(mediaData); | |
229 | |
230 test.waitForExpectedEvents(function() | |
231 { | |
232 assert_equals(mediaElement.duration, fullDuration, 'mediaEleme nt fullDuration'); | |
233 assert_equals(mediaSource.duration, fullDuration, 'mediaSource fullDuration'); | |
234 | |
235 // TODO(wolenetz): Fine-tune this test to use the buffered att ribute's highest end time | |
236 // instead of fullDuration once Chrome correctly reports buffe red PTS, not DTS. | |
237 // See https://crbug.com/398130. | |
238 | |
239 // Setting duration to same as current, or increasing it, shou ld not trigger exception. | |
240 mediaSource.duration = fullDuration; | |
241 mediaSource.duration = fullDuration + 1; | |
242 | |
243 // Reducing duration to below the highest buffered PTS should trigger exception. | |
244 assert_throws('InvalidStateError', | |
245 function() { mediaSource.duration = fullDuration - 0.05; } , | |
246 'Duration reduction that truncates at least one whole code d frame throws an exception.'); | |
247 | |
248 assert_equals(mediaSource.duration, fullDuration + 1, 'mediaSo urce fullDuration'); | |
249 | |
250 // Reducing duration without truncating any buffered media sho uld not trigger exception. | |
251 mediaSource.duration = fullDuration; | |
252 | |
253 // Reducing duration by less then the minimum of the last test audio and video frame | |
254 // durations should not trigger exception. | |
255 mediaSource.duration = fullDuration - 0.001; | |
256 test.done(); | |
257 }); | |
258 }, 'Test duration reduction below highest buffered presentation time i s disallowed'); | |
259 | |
209 </script> | 260 </script> |
210 </body> | 261 </body> |
211 </html> | 262 </html> |
OLD | NEW |