summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/media-source/mediasource-sequencemode-append-buffer.html
blob: 92a01abcc0ef473a7527e1ab29ba49344669adb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<!DOCTYPE html>
<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
<html>
    <head>
        <title>SourceBuffer.mode == "sequence" test cases.</title>
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
        <script src="mediasource-util.js"></script>
    </head>
    <body>
        <div id="log"></div>
        <script>
          function mediasource_sequencemode_test(testFunction, description, options)
          {
              return mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
              {
                  assert_greater_than(segmentInfo.media.length, 3, "at least 3 media segments for supported type");
                  mediaElement.addEventListener("error", test.unreached_func("Unexpected event 'error'"));
                  sourceBuffer.mode = "sequence";
                  assert_equals(sourceBuffer.mode, "sequence", "mode after setting it to \"sequence\"");

                  var initSegment = MediaSourceUtil.extractSegmentData(mediaData, segmentInfo.init);
                  test.expectEvent(sourceBuffer, "updatestart", "initSegment append started.");
                  test.expectEvent(sourceBuffer, "update", "initSegment append success.");
                  test.expectEvent(sourceBuffer, "updateend", "initSegment append ended.");
                  sourceBuffer.appendBuffer(initSegment);
                  test.waitForExpectedEvents(function()
                  {
                      assert_equals(sourceBuffer.timestampOffset, 0, "timestampOffset initially 0");
                      testFunction(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData);
                  });
              }, description, options);
          }

          function append_segment(test, sourceBuffer, mediaData, info, callback)
          {
              var mediaSegment = MediaSourceUtil.extractSegmentData(mediaData, info);
              test.expectEvent(sourceBuffer, "updatestart", "media segment append started.");
              test.expectEvent(sourceBuffer, "update", "media segment append success.");
              test.expectEvent(sourceBuffer, "updateend", "media segment append ended.");
              sourceBuffer.appendBuffer(mediaSegment);
              test.waitForExpectedEvents(callback);
          }

          function threeDecimalPlaces(number)
          {
              return Number(number.toFixed(3));
          }

          // Verifies expected times to 3 decimal places before and after mediaSource.endOfStream(),
          // and calls |callback| on success.
          function verify_offset_and_buffered(test, mediaSource, sourceBuffer,
                                              expectedTimestampOffset, expectedBufferedRangeStartTime,
                                              expectedBufferedRangeMaxEndTimeBeforeEOS,
                                              expectedBufferedRangeEndTimeAfterEOS,
                                              callback) {
              assert_equals(threeDecimalPlaces(sourceBuffer.timestampOffset),
                            threeDecimalPlaces(expectedTimestampOffset),
                            "expectedTimestampOffset");

              // Prior to EOS, the buffered range end time may not have fully reached the next media
              // segment's timecode (adjusted by any timestampOffset). It should not exceed it though.
              // Therefore, an exact assertBufferedEquals() will not work here.
              assert_greater_than(sourceBuffer.buffered.length, 0, "sourceBuffer.buffered has at least 1 range before EOS");
              assert_equals(threeDecimalPlaces(sourceBuffer.buffered.start(0)),
                            threeDecimalPlaces(expectedBufferedRangeStartTime),
                            "sourceBuffer.buffered range begins where expected before EOS");
              assert_less_than_equal(threeDecimalPlaces(sourceBuffer.buffered.end(0)),
                                     threeDecimalPlaces(expectedBufferedRangeMaxEndTimeBeforeEOS),
                                     "sourceBuffer.buffered range ends at or before expected upper bound before EOS");

              test.expectEvent(mediaSource, "sourceended", "mediaSource endOfStream");
              mediaSource.endOfStream();
              test.waitForExpectedEvents(function()
              {
                  assertBufferedEquals(sourceBuffer,
                                       "{ [" + expectedBufferedRangeStartTime.toFixed(3) + ", " + expectedBufferedRangeEndTimeAfterEOS.toFixed(3) + ") }",
                                       "sourceBuffer.buffered after EOS");
                  callback();
              });
          }

          mediasource_sequencemode_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
          {
              var offset = Math.min(segmentInfo.media[0].timev, segmentInfo.media[0].timea);
              var expectedStart = Math.max(segmentInfo.media[0].timev, segmentInfo.media[0].timea) - offset;
              var expectedEnd = Math.min(segmentInfo.media[0].endtimev, segmentInfo.media[0].endtimea) - offset;
              var expectedEndEOS = Math.max(segmentInfo.media[0].endtimev, segmentInfo.media[0].endtimea) - offset;
              append_segment(test, sourceBuffer, mediaData, segmentInfo.media[0], function()
              {
                  verify_offset_and_buffered(test, mediaSource, sourceBuffer,
                                             -offset, expectedStart,
                                             expectedEnd, expectedEndEOS,
                                             test.done);
              });
          }, "Test sequence AppendMode appendBuffer(first media segment)");

          mediasource_sequencemode_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
          {
              var offset = Math.min(segmentInfo.media[1].timev, segmentInfo.media[1].timea);
              var expectedStart = Math.max(segmentInfo.media[1].timev, segmentInfo.media[1].timea) - offset;
              var expectedEnd = Math.min(segmentInfo.media[1].endtimev, segmentInfo.media[1].endtimea) - offset;
              var expectedEndEOS = Math.max(segmentInfo.media[1].endtimev, segmentInfo.media[1].endtimea) - offset;
              assert_greater_than(Math.min(segmentInfo.media[1].timev, segmentInfo.media[1].timea), 0,
                                  "segment starts after time 0");
              append_segment(test, sourceBuffer, mediaData, segmentInfo.media[1], function()
              {
                  verify_offset_and_buffered(test, mediaSource, sourceBuffer,
                                             -offset, expectedStart,
                                             expectedEnd, expectedEndEOS,
                                             test.done);
              });
          }, "Test sequence AppendMode appendBuffer(second media segment)");

          mediasource_sequencemode_test(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
          {
              assert_greater_than(Math.min(segmentInfo.media[1].timev, segmentInfo.media[1].timea), 0,
                                  "segment starts after time 0");
              append_segment(test, sourceBuffer, mediaData, segmentInfo.media[1], function()
              {
                  append_segment(test, sourceBuffer, mediaData, segmentInfo.media[0], function()
                  {
                      var firstOffset = Math.min(segmentInfo.media[1].timev, segmentInfo.media[1].timea);
                      var secondOffset = Math.max(segmentInfo.media[1].endtimev, segmentInfo.media[1].endtimea) - firstOffset;
                      var expectedStart = Math.max(segmentInfo.media[1].timev, segmentInfo.media[1].timea) - firstOffset;
                      var expectedEnd = Math.min(segmentInfo.media[0].endtimev, segmentInfo.media[0].endtimea) + secondOffset;
                      var expectedEndEOS = Math.max(segmentInfo.media[0].endtimev, segmentInfo.media[0].endtimea) + secondOffset;
                      // Current timestampOffset should reflect offset required to put media[0]
                      // immediately after media[1]'s highest frame end timestamp (as was adjusted
                      // by an earlier timestampOffset).
                      verify_offset_and_buffered(test, mediaSource, sourceBuffer,
                                                 secondOffset, expectedStart,
                                                 expectedEnd, expectedEndEOS,
                                                 test.done);
                  })
              });
          }, "Test sequence AppendMode appendBuffer(second media segment, then first media segment)");
        </script>
    </body>
</html>