| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 1 | <!DOCTYPE html> | 
| Matt Wolenetz | 74803c6 | 2016-08-19 01:46:40 | [diff] [blame] | 2 | <!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). --> | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 3 | <html> | 
 | 4 |  <head> | 
| Aaron Colwell | aa3c90b | 2014-08-04 17:58:37 | [diff] [blame] | 5 |  <title>SourceBuffer.buffered test cases.</title> | 
| Aaron Colwell | 06f8ec2 | 2014-03-07 18:09:47 | [diff] [blame] | 6 |  <script src="/resources/testharness.js"></script> | 
 | 7 |  <script src="/resources/testharnessreport.js"></script> | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 8 |  <script src="mediasource-util.js"></script> | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 9 |  </head> | 
 | 10 |  <body> | 
 | 11 |  <div id="log"></div> | 
 | 12 |  <script> | 
 | 13 |  var subType = MediaSourceUtil.getSubType(MediaSourceUtil.AUDIO_ONLY_TYPE); | 
 | 14 |  | 
 | 15 |  var manifestFilenameA = subType + "/test-a-128k-44100Hz-1ch-manifest.json"; | 
 | 16 |  var manifestFilenameB = subType + "/test-v-128k-320x240-30fps-10kfr-manifest.json"; | 
 | 17 |  | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 18 |  // Audio track expectations | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 19 |  var expectationsA = { | 
| Jan Gerber | 1ac73d8 | 2015-08-25 13:40:31 | [diff] [blame] | 20 |  webm: "{ [0.000, 2.023) }", | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 21 |  mp4: "{ [0.000, 2.043) }", | 
 | 22 |  }; | 
 | 23 |  | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 24 |  // Video track expectations | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 25 |  var expectationsB = { | 
| Jan Gerber | 1ac73d8 | 2015-08-25 13:40:31 | [diff] [blame] | 26 |  webm: "{ [0.000, 2.001) }", | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 27 |  mp4: "{ [0.067, 2.067) }", | 
 | 28 |  }; | 
 | 29 |  | 
 | 30 |  // Audio and Video intersection expectations. | 
 | 31 |  // https://w3c.github.io/media-source/index.html#dom-sourcebuffer-buffered | 
 | 32 |  // When mediaSource.readyState is "ended", then set the end time on the last range in track ranges to highest end time. | 
 | 33 |  var expectationsC = { | 
 | 34 |  webm: ["{ [0.000, 2.001) }", "{ [0.000, 2.023) }"], | 
 | 35 |  mp4: ["{ [0.067, 2.043) }", "{ [0.067, 2.067) }"] | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 36 |  }; | 
 | 37 |  | 
 | 38 |  function mediaSourceDemuxedTest(callback, description) | 
 | 39 |  { | 
 | 40 |  mediasource_test(function(test, mediaElement, mediaSource) | 
 | 41 |  { | 
 | 42 |  mediaElement.pause(); | 
| Ms2ger | 979de36 | 2015-06-29 10:21:19 | [diff] [blame] | 43 |  mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'")); | 
| Ms2ger | edb207d | 2015-06-29 10:31:57 | [diff] [blame] | 44 |  mediaElement.addEventListener("ended", test.step_func_done()); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 45 |  | 
 | 46 |  MediaSourceUtil.fetchManifestAndData(test, manifestFilenameA, function(typeA, dataA) | 
 | 47 |  { | 
 | 48 |  MediaSourceUtil.fetchManifestAndData(test, manifestFilenameB, function(typeB, dataB) | 
 | 49 |  { | 
 | 50 |  mediaSource.addSourceBuffer(typeA); | 
 | 51 |  mediaSource.addSourceBuffer(typeB); | 
| Aaron Colwell | cffb8af | 2014-05-23 22:27:10 | [diff] [blame] | 52 |  assert_equals(mediaSource.sourceBuffers.length, 2); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 53 |  | 
 | 54 |  callback(test, mediaElement, mediaSource, dataA, dataB); | 
 | 55 |  }); | 
 | 56 |  }); | 
 | 57 |  }, description); | 
 | 58 |  }; | 
 | 59 |  | 
 | 60 |  function appendData(test, mediaSource, dataA, dataB, callback) | 
 | 61 |  { | 
| Aaron Colwell | cffb8af | 2014-05-23 22:27:10 | [diff] [blame] | 62 |  var sourceBufferA = mediaSource.sourceBuffers[0]; | 
 | 63 |  var sourceBufferB = mediaSource.sourceBuffers[1]; | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 64 |  | 
 | 65 |  test.expectEvent(sourceBufferA, "update"); | 
 | 66 |  test.expectEvent(sourceBufferA, "updateend"); | 
 | 67 |  sourceBufferA.appendBuffer(dataA); | 
 | 68 |  | 
 | 69 |  test.expectEvent(sourceBufferB, "update"); | 
 | 70 |  test.expectEvent(sourceBufferB, "updateend"); | 
 | 71 |  sourceBufferB.appendBuffer(dataB); | 
 | 72 |  | 
 | 73 |  test.waitForExpectedEvents(function() | 
 | 74 |  { | 
 | 75 |  callback(); | 
 | 76 |  }); | 
 | 77 |  } | 
 | 78 |  | 
 | 79 |  mediaSourceDemuxedTest(function(test, mediaElement, mediaSource, dataA, dataB) { | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 80 |  test.expectEvent(mediaElement, "loadedmetadata"); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 81 |  appendData(test, mediaSource, dataA, dataB, function() | 
 | 82 |  { | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 83 |  var expectedBeforeEndOfStreamIntersection = expectationsC[subType][0]; | 
 | 84 |  var expectedAfterEndOfStreamIntersection = expectationsC[subType][1]; | 
 | 85 |  | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 86 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], "mediaSource.activeSourceBuffers[0]"); | 
 | 87 |  assertBufferedEquals(mediaSource.activeSourceBuffers[1], expectationsB[subType], "mediaSource.activeSourceBuffers[1]"); | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 88 |  assertBufferedEquals(mediaElement, expectedBeforeEndOfStreamIntersection, "mediaElement.buffered"); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 89 |  | 
 | 90 |  mediaSource.endOfStream(); | 
 | 91 |  | 
 | 92 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], "mediaSource.activeSourceBuffers[0]"); | 
 | 93 |  assertBufferedEquals(mediaSource.activeSourceBuffers[1], expectationsB[subType], "mediaSource.activeSourceBuffers[1]"); | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 94 |  assertBufferedEquals(mediaElement, expectedAfterEndOfStreamIntersection, "mediaElement.buffered"); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 95 |  | 
 | 96 |  test.done(); | 
 | 97 |  }); | 
 | 98 |  }, "Demuxed content with different lengths"); | 
 | 99 |  | 
 | 100 |  mediasource_test(function(test, mediaElement, mediaSource) | 
 | 101 |  { | 
 | 102 |  mediaElement.pause(); | 
| Ms2ger | 979de36 | 2015-06-29 10:21:19 | [diff] [blame] | 103 |  mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'")); | 
| Ms2ger | edb207d | 2015-06-29 10:31:57 | [diff] [blame] | 104 |  mediaElement.addEventListener("ended", test.step_func_done()); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 105 |  | 
 | 106 |  MediaSourceUtil.fetchManifestAndData(test, subType + "/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr-manifest.json", function(type, data) | 
 | 107 |  { | 
 | 108 |  var sourceBuffer = mediaSource.addSourceBuffer(type); | 
 | 109 |  test.expectEvent(sourceBuffer, "update"); | 
 | 110 |  test.expectEvent(sourceBuffer, "updateend"); | 
 | 111 |  sourceBuffer.appendBuffer(data); | 
 | 112 |  | 
 | 113 |  test.waitForExpectedEvents(function() | 
 | 114 |  { | 
 | 115 |  var expectationsAV = { | 
| Jean-Yves Avenard | 0b35fdb | 2016-08-25 12:56:59 | [diff] [blame] | 116 |  webm: ["{ [0.003, 2.004) }", "{ [0.003, 2.023) }"], | 
 | 117 |  mp4: ["{ [0.067, 2.043) }", "{ [0.067, 2.067) }"], | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 118 |  }; | 
 | 119 |  | 
 | 120 |  var expectedBeforeEndOfStream = expectationsAV[subType][0]; | 
 | 121 |  var expectedAfterEndOfStream = expectationsAV[subType][1]; | 
 | 122 |  | 
 | 123 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectedBeforeEndOfStream, "mediaSource.activeSourceBuffers[0]"); | 
 | 124 |  assertBufferedEquals(mediaElement, expectedBeforeEndOfStream, "mediaElement.buffered"); | 
 | 125 |  | 
 | 126 |  mediaSource.endOfStream(); | 
 | 127 |  | 
 | 128 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectedAfterEndOfStream, "mediaSource.activeSourceBuffers[0]"); | 
 | 129 |  assertBufferedEquals(mediaElement, expectedAfterEndOfStream, "mediaElement.buffered"); | 
 | 130 |  | 
 | 131 |  test.done(); | 
 | 132 |  }); | 
 | 133 |  }); | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 134 |  }, "Muxed content with different lengths"); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 135 |  | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 136 |  mediaSourceDemuxedTest(function(test, mediaElement, mediaSource, dataA, dataB) { | 
| Aaron Colwell | cffb8af | 2014-05-23 22:27:10 | [diff] [blame] | 137 |  var dataBSize = { | 
 | 138 |  webm: 318, | 
| Aaron Colwell | 795cb53 | 2014-08-07 16:35:39 | [diff] [blame] | 139 |  mp4: 835, | 
| Aaron Colwell | cffb8af | 2014-05-23 22:27:10 | [diff] [blame] | 140 |  }; | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 141 |  test.expectEvent(mediaElement, "loadedmetadata"); | 
| Aaron Colwell | cffb8af | 2014-05-23 22:27:10 | [diff] [blame] | 142 |  appendData(test, mediaSource, dataA, dataB.subarray(0, dataBSize[subType]), function() | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 143 |  { | 
 | 144 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], "mediaSource.activeSourceBuffers[0]"); | 
 | 145 |  assertBufferedEquals(mediaSource.activeSourceBuffers[1], "{ }", "mediaSource.activeSourceBuffers[1]"); | 
 | 146 |  assertBufferedEquals(mediaElement, "{ }", "mediaElement.buffered"); | 
 | 147 |  | 
 | 148 |  mediaSource.endOfStream(); | 
 | 149 |  | 
 | 150 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], expectationsA[subType], "mediaSource.activeSourceBuffers[0]"); | 
 | 151 |  assertBufferedEquals(mediaSource.activeSourceBuffers[1], "{ }", "mediaSource.activeSourceBuffers[1]"); | 
 | 152 |  assertBufferedEquals(mediaElement, "{ }", "mediaElement.buffered"); | 
 | 153 |  | 
 | 154 |  test.done(); | 
 | 155 |  }); | 
 | 156 |  }, "Demuxed content with an empty buffered range on one SourceBuffer"); | 
 | 157 |  | 
 | 158 |  mediasource_test(function(test, mediaElement, mediaSource) | 
 | 159 |  { | 
 | 160 |  mediaElement.pause(); | 
| Ms2ger | 979de36 | 2015-06-29 10:21:19 | [diff] [blame] | 161 |  mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'")); | 
| Ms2ger | edb207d | 2015-06-29 10:31:57 | [diff] [blame] | 162 |  mediaElement.addEventListener("ended", test.step_func_done()); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 163 |  | 
 | 164 |  MediaSourceUtil.fetchManifestAndData(test, subType + "/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr-manifest.json", function(type, data) | 
 | 165 |  { | 
 | 166 |  var sourceBuffer = mediaSource.addSourceBuffer(type); | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 167 |  test.expectEvent(mediaElement, "loadedmetadata"); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 168 |  test.expectEvent(sourceBuffer, "update"); | 
 | 169 |  test.expectEvent(sourceBuffer, "updateend"); | 
 | 170 |  sourceBuffer.appendBuffer(data.subarray(0, 4052)); | 
 | 171 |  | 
 | 172 |  test.waitForExpectedEvents(function() | 
 | 173 |  { | 
 | 174 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], "{ }", "mediaSource.activeSourceBuffers[0]"); | 
 | 175 |  assertBufferedEquals(mediaElement, "{ }", "mediaElement.buffered"); | 
 | 176 |  | 
 | 177 |  mediaSource.endOfStream(); | 
 | 178 |  | 
 | 179 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], "{ }", "mediaSource.activeSourceBuffers[0]"); | 
 | 180 |  assertBufferedEquals(mediaElement, "{ }", "mediaElement.buffered"); | 
 | 181 |  | 
 | 182 |  test.done(); | 
 | 183 |  }); | 
 | 184 |  }); | 
 | 185 |  }, "Muxed content empty buffered ranges."); | 
| Aaron Colwell | cffb8af | 2014-05-23 22:27:10 | [diff] [blame] | 186 |  | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 187 |  mediasource_test(function(test, mediaElement, mediaSource) | 
 | 188 |  { | 
 | 189 |  mediaElement.pause(); | 
| Ms2ger | 979de36 | 2015-06-29 10:21:19 | [diff] [blame] | 190 |  mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'")); | 
| Ms2ger | edb207d | 2015-06-29 10:31:57 | [diff] [blame] | 191 |  mediaElement.addEventListener("ended", test.step_func_done()); | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 192 |  | 
 | 193 |  var sourceBuffer = mediaSource.addSourceBuffer(MediaSourceUtil.AUDIO_ONLY_TYPE); | 
 | 194 |  | 
 | 195 |  assertBufferedEquals(mediaSource.sourceBuffers[0], "{ }", "mediaSource.sourceBuffers[0]"); | 
 | 196 |  assertBufferedEquals(mediaElement, "{ }", "mediaElement.buffered"); | 
 | 197 |  test.done(); | 
 | 198 |  | 
 | 199 |  }, "Get buffered range when sourcebuffer is empty."); | 
 | 200 |  | 
 | 201 |  mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) | 
 | 202 |  { | 
 | 203 |  var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init); | 
 | 204 |  | 
 | 205 |  test.expectEvent(mediaElement, "loadedmetadata"); | 
 | 206 |  test.expectEvent(sourceBuffer, "updateend", "initSegment append ended."); | 
 | 207 |  sourceBuffer.appendBuffer(initSegment); | 
 | 208 |  test.waitForExpectedEvents(function() | 
 | 209 |  { | 
 | 210 |  assertBufferedEquals(mediaSource.sourceBuffers[0], "{ }", "mediaSource.sourceBuffers[0]"); | 
 | 211 |  assertBufferedEquals(mediaSource.activeSourceBuffers[0], "{ }", "mediaSource.activeSourceBuffers[0]"); | 
 | 212 |  assertBufferedEquals(mediaElement, "{ }", "mediaElement.buffered"); | 
 | 213 |  test.done(); | 
 | 214 |  }); | 
 | 215 |  | 
 | 216 |  }, "Get buffered range when only init segment is appended."); | 
 | 217 |  | 
 | 218 |  mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData) | 
 | 219 |  { | 
 | 220 |  test.expectEvent(mediaSource.sourceBuffers, "removesourcebuffer", "SourceBuffer removed."); | 
 | 221 |  mediaSource.removeSourceBuffer(sourceBuffer); | 
 | 222 |  | 
 | 223 |  test.waitForExpectedEvents(function() | 
 | 224 |  { | 
| Stephen McGruer | 3696f22 | 2020-01-23 19:11:58 | [diff] [blame] | 225 |  assert_throws_dom("InvalidStateError", | 
| Aaron Colwell | ab0ee7b | 2014-09-09 21:10:39 | [diff] [blame] | 226 |  function() { sourceBuffer.buffered; }, | 
 | 227 |  "get sourceBuffer.buffered throws an exception for InvalidStateError."); | 
 | 228 |  test.done(); | 
 | 229 |  }); | 
 | 230 |  }, "Get buffered range after removing sourcebuffer."); | 
| Aaron Colwell | c6841a0 | 2014-03-07 01:37:56 | [diff] [blame] | 231 |  </script> | 
 | 232 |  </body> | 
 | 233 | </html> |