tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mediasource-webcodecs-addsourcebuffer.html (6753B)


      1 <!DOCTYPE html>
      2 <html>
      3  <title>Test MediaSource addSourceBuffer overloads for WebCodecs Audio/VideoDecoderConfigs</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script>
      7 
      8 setup(() => {
      9  assert_implements(
     10      SourceBuffer.prototype.hasOwnProperty('appendEncodedChunks'),
     11      'SourceBuffer prototype hasOwnProperty "appendEncodedChunks", used ' +
     12          'here to feature detect MSE-for-WebCodecs implementation.');
     13 });
     14 
     15 testInvalidArguments();
     16 testValidArguments();
     17 
     18 function getValidAudioConfig() {
     19  // TODO(crbug.com/1144908): Consider confirming with WebCodecs'
     20  // isConfigSupported() once that API is available.
     21  return {
     22    codec: 'opus',
     23    sampleRate: 48000,
     24    numberOfChannels: 2
     25  };
     26 }
     27 
     28 function getValidVideoConfig() {
     29  // TODO(crbug.com/1144908): Consider confirming with WebCodecs'
     30  // isConfigSupported() once that API is available.
     31  return { codec: 'vp09.00.10.08' };
     32 }
     33 
     34 function testInvalidArguments() {
     35  const INVALID_CASES = [
     36    { arg: null,
     37      name: 'null' },
     38    { arg: undefined,
     39      name: 'undefined' },
     40    { arg: { },
     41      name: '{ empty dictionary }' },
     42    {
     43      arg: {
     44        audioConfig: getValidAudioConfig(),
     45        videoConfig: getValidVideoConfig()
     46      },
     47      name: '{ valid audioConfig and videoConfig }',
     48    },
     49    { arg: { audioConfig: { sampleRate: 48000, numberOfChannels: 2 } },
     50      name: 'audio config missing required member "codec"' },
     51    { arg: { videoConfig: { } },
     52      name: 'video config missing required member "codec"' },
     53  ];
     54 
     55  [ 'closed', 'open', 'ended' ].forEach(readyStateScenario => {
     56    INVALID_CASES.forEach(invalidCase => {
     57      runAddSourceBufferTest(invalidCase['arg'] /* argument */,
     58          false /* isValidArgument */,
     59          invalidCase['name'] /* argumentDescription */,
     60          readyStateScenario);
     61    });
     62  });
     63 }
     64 
     65 function testValidArguments() {
     66  const VALID_CASES = [
     67    {
     68      arg: {
     69        audioConfig: getValidAudioConfig()
     70      },
     71      name: 'valid audioConfig'
     72    },
     73    {
     74      arg: {
     75        videoConfig: getValidVideoConfig()
     76      },
     77      name: 'valid videoConfig'
     78    },
     79  ];
     80 
     81  [ 'closed', 'open', 'ended' ].forEach(readyStateScenario => {
     82    VALID_CASES.forEach(validCase => {
     83      runAddSourceBufferTest(
     84          validCase['arg'] /* argument */,
     85          true /* isValidArgument */,
     86          validCase['name'] /* argumentDescription */,
     87          readyStateScenario);
     88    });
     89  });
     90 }
     91 
     92 async function getClosedMediaSource(test) {
     93  let mediaSource = new MediaSource();
     94  assert_equals(mediaSource.readyState, 'closed');
     95  return mediaSource;
     96 }
     97 
     98 async function getOpenMediaSource(test) {
     99  return new Promise(async resolve => {
    100    const v = document.createElement('video');
    101    const mediaSource = new MediaSource();
    102    const url = URL.createObjectURL(mediaSource);
    103    mediaSource.addEventListener('sourceopen', test.step_func(() => {
    104      URL.revokeObjectURL(url);
    105      assert_equals(mediaSource.readyState, 'open', 'MediaSource is open');
    106      resolve(mediaSource);
    107    }), { once: true });
    108    v.src = url;
    109  });
    110 }
    111 
    112 async function getEndedMediaSource(test) {
    113  let mediaSource = await getOpenMediaSource(test);
    114  assert_equals(mediaSource.readyState, 'open', 'MediaSource is open');
    115  mediaSource.endOfStream();
    116  assert_equals(mediaSource.readyState, 'ended', 'MediaSource is ended');
    117  return mediaSource;
    118 }
    119 
    120 function runAddSourceBufferTest(argument, isValidArgument, argumentDescription, readyStateScenario) {
    121  const testDescription = 'addSourceBuffer call with ' +
    122      (isValidArgument ? 'valid' : 'invalid') +
    123      ' argument ' + argumentDescription + ' while MediaSource readyState is ' +
    124      readyStateScenario;
    125 
    126  switch(readyStateScenario) {
    127    case 'closed':
    128      promise_test(async t => {
    129        let mediaSource = await getClosedMediaSource(t);
    130        assert_equals(mediaSource.readyState, 'closed');
    131        let sourceBuffer;
    132        if (isValidArgument) {
    133          assert_throws_dom('InvalidStateError',
    134              () => { sourceBuffer = mediaSource.addSourceBuffer(argument); },
    135              'addSourceBuffer(valid config) throws InvalidStateError if MediaSource is "closed"');
    136          assert_equals(sourceBuffer, undefined,
    137              'addSourceBuffer result for valid config while "closed" should be exception');
    138        } else {
    139          assert_throws_js(TypeError,
    140              () => { sourceBuffer = mediaSource.addSourceBuffer(argument); },
    141              'addSourceBuffer(invalid config) throws TypeError if MediaSource is "closed"');
    142          assert_equals(sourceBuffer, undefined,
    143              'addSourceBuffer result for invalid config while "closed" should be exception');
    144        }
    145      }, testDescription);
    146      break;
    147    case 'open':
    148      promise_test(async t => {
    149        let mediaSource = await getOpenMediaSource(t);
    150        assert_equals(mediaSource.readyState, 'open', 'MediaSource is open');
    151        let sourceBuffer;
    152        if (isValidArgument) {
    153          sourceBuffer = mediaSource.addSourceBuffer(argument);
    154          assert_true(sourceBuffer instanceof SourceBuffer,
    155              'addSourceBuffer result for valid config while "open" should be a SourceBuffer instance');
    156        } else {
    157          assert_throws_js(TypeError,
    158              () => { sourceBuffer = mediaSource.addSourceBuffer(argument); },
    159              'addSourceBuffer(invalid config) throws TypeError if MediaSource is "open"');
    160          assert_equals(sourceBuffer, undefined,
    161              'addSourceBufferResult for invalid config while "open" should be exception');
    162        }
    163      }, testDescription);
    164      break;
    165    case 'ended':
    166      promise_test(async t => {
    167        let mediaSource = await getEndedMediaSource(t);
    168        let sourceBuffer;
    169        if (isValidArgument) {
    170          assert_throws_dom('InvalidStateError',
    171              () => { sourceBuffer = mediaSource.addSourceBuffer(argument); },
    172              'addSourceBuffer(valid config) throws InvalidStateError if MediaSource is "ended"');
    173          assert_equals(sourceBuffer, undefined,
    174              'addSourceBuffer result for valid config while "ended" should be exception');
    175        } else {
    176          assert_throws_js(TypeError,
    177              () => { sourceBuffer = mediaSource.addSourceBuffer(argument); },
    178              'addSourceBuffer(invalid config) throws TypeError if MediaSource is "ended"');
    179          assert_equals(sourceBuffer, undefined,
    180              'addSourceBuffer result for invalid config while "ended" should be exception');
    181        }
    182      }, testDescription);
    183      break;
    184    default:
    185      assert_unreached('Invalid readyStateScenario ' + readyStateScenario);
    186      break;
    187  }
    188 }
    189 
    190 </script>
    191 </html>