// META: global=window,dedicatedworker
// META: script=videoDecoder-codec-specific-setup.js
// META: variant=?av1
// META: variant=?vp8
// META: variant=?vp9
// META: variant=?h264_avc
// META: variant=?h264_annexb
// META: variant=?h265_hevc
// META: variant=?h265_annexb

promise_test(async t => {
  await checkImplements();
  const support = await VideoDecoder.isConfigSupported(CONFIG);
  assert_true(support.supported, 'supported');
}, 'Test isConfigSupported()');

promise_test(async t => {
  await checkImplements();
  // TODO(sandersd): Create a 1080p `description` for H.264 in AVC format.
  // This version is testing only the H.264 Annex B path.
  const config = {
    codec: CONFIG.codec,
    codedWidth: 1920,
    codedHeight: 1088,
    displayAspectWidth: 1920,
    displayAspectHeight: 1080,
  };

  const support = await VideoDecoder.isConfigSupported(config);
  assert_true(support.supported, 'supported');
}, 'Test isConfigSupported() with 1080p crop');

promise_test(async t => {
  await checkImplements();
  // Define a valid config that includes a hypothetical `futureConfigFeature`,
  // which is not yet recognized by the User Agent.
  const config = {
    ...CONFIG,
    colorSpace: {primaries: 'bt709'},
    futureConfigFeature: 'foo',
  };

  // The UA will evaluate validConfig as being "valid", ignoring the
  // `futureConfigFeature` it  doesn't recognize.
  const support = await VideoDecoder.isConfigSupported(config);
  assert_true(support.supported, 'supported');
  assert_equals(support.config.codec, config.codec, 'codec');
  assert_equals(support.config.codedWidth, config.codedWidth, 'codedWidth');
  assert_equals(support.config.codedHeight, config.codedHeight, 'codedHeight');
  assert_equals(support.config.displayAspectWidth, config.displayAspectWidth, 'displayAspectWidth');
  assert_equals(support.config.displayAspectHeight, config.displayAspectHeight, 'displayAspectHeight');
  assert_equals(support.config.colorSpace.primaries, config.colorSpace.primaries, 'color primaries');
  assert_equals(support.config.colorSpace.transfer, null, 'color transfer');
  assert_equals(support.config.colorSpace.matrix, null, 'color matrix');
  assert_equals(support.config.colorSpace.fullRange, null, 'color range');
  assert_false(support.config.hasOwnProperty('futureConfigFeature'), 'futureConfigFeature');

  if (config.description) {
    // The description must be copied.
    assert_false(
        support.config.description === config.description,
        'description is unique');
    assert_array_equals(
        new Uint8Array(support.config.description, 0),
        new Uint8Array(config.description, 0), 'description');
  } else {
    assert_false(support.config.hasOwnProperty('description'), 'description');
  }
}, 'Test that isConfigSupported() returns a parsed configuration');

promise_test(async t => {
  await checkImplements();
  async function test(t, config, description) {
    await promise_rejects_js(
        t, TypeError, VideoDecoder.isConfigSupported(config), description);

    const decoder = createVideoDecoder(t);
    assert_throws_js(TypeError, () => decoder.configure(config), description);
    assert_equals(decoder.state, 'unconfigured', 'state');
  }

  await test(t, {...CONFIG, codedWidth: 0}, 'invalid codedWidth');
  await test(t, {...CONFIG, displayAspectWidth: 0}, 'invalid displayAspectWidth');
}, 'Test invalid configs');

promise_test(async t => {
  await checkImplements();
  const decoder = createVideoDecoder(t);
  decoder.configure(CONFIG);
  assert_equals(decoder.state, 'configured', 'state');
}, 'Test configure()');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);

  let outputs = 0;
  callbacks.output = frame => {
    outputs++;
    assert_equals(frame.timestamp, CHUNKS[0].timestamp, 'timestamp');
    assert_equals(frame.duration, CHUNKS[0].duration, 'duration');
    frame.close();
  };

  await decoder.flush();
  assert_equals(outputs, 1, 'outputs');
}, 'Decode a key frame');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);

  // Ensure type value is verified.
  assert_equals(CHUNKS[1].type, 'delta');
  assert_throws_dom('DataError', () => decoder.decode(CHUNKS[1], 'decode'));
}, 'Decode a non key frame first fails');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);

  // Mark a keyframe chunk as a delta chunk to ensure any packet analysis
  // doesn't override the user provided type.
  let mismarked_chunk = new EncodedVideoChunk(
      {type: 'delta', timestamp: 0, duration: 1, data: CHUNK_DATA[0]});

  assert_throws_dom(
      'DataError', () => decoder.decode(mismarked_chunk, 'decode'));
}, 'Decode a key frame marked as delta fails');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);
  for (let i = 0; i < 16; i++) {
    decoder.decode(new EncodedVideoChunk(
        {type: 'key', timestamp: 0, data: CHUNK_DATA[0]}));
  }
  assert_greater_than(decoder.decodeQueueSize, 0);

  // Wait for the first output, then reset the decoder.
  let outputs = 0;
  await new Promise(resolve => {
    callbacks.output = frame => {
      outputs++;
      assert_equals(outputs, 1, 'outputs');
      assert_equals(frame.timestamp, 0, 'timestamp');
      frame.close();
      decoder.reset();
      assert_equals(decoder.decodeQueueSize, 0, 'decodeQueueSize');
      resolve();
    };
  });

  decoder.configure(CONFIG);
  for (let i = 0; i < 4; i++) {
    decoder.decode(new EncodedVideoChunk(
        {type: 'key', timestamp: 1, data: CHUNK_DATA[0]}));
  }

  // Expect future outputs to come from after the reset.
  callbacks.output = frame => {
    outputs++;
    assert_equals(frame.timestamp, 1, 'timestamp');
    frame.close();
  };

  await decoder.flush();
  assert_equals(outputs, 5);
  assert_equals(decoder.decodeQueueSize, 0);
}, 'Verify reset() suppresses outputs');

promise_test(async t => {
  await checkImplements();
  const decoder = createVideoDecoder(t);
  assert_equals(decoder.state, 'unconfigured');

  decoder.reset();
  assert_equals(decoder.state, 'unconfigured');
  assert_throws_dom(
      'InvalidStateError', () => decoder.decode(CHUNKS[0]), 'decode');
  await promise_rejects_dom(t, 'InvalidStateError', decoder.flush(), 'flush');
}, 'Test unconfigured VideoDecoder operations');

promise_test(async t => {
  await checkImplements();
  const decoder = createVideoDecoder(t);
  decoder.close();
  assert_equals(decoder.state, 'closed');
  assert_throws_dom(
      'InvalidStateError', () => decoder.configure(CONFIG), 'configure');
  assert_throws_dom('InvalidStateError', () => decoder.reset(), 'reset');
  assert_throws_dom('InvalidStateError', () => decoder.close(), 'close');
  assert_throws_dom(
      'InvalidStateError', () => decoder.decode(CHUNKS[0]), 'decode');
  await promise_rejects_dom(t, 'InvalidStateError', decoder.flush(), 'flush');
}, 'Test closed VideoDecoder operations');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};

  let errors = 0;
  let gotError = new Promise(resolve => callbacks.error = e => {
    errors++;
    resolve(e);
  });
  callbacks.output = frame => { frame.close(); };

  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);  // Decode keyframe first.
  decoder.decode(new EncodedVideoChunk(
      {type: 'key', timestamp: 1, data: new ArrayBuffer(0)}));

  await promise_rejects_dom(t, "EncodingError",
    decoder.flush().catch((e) => {
      assert_equals(errors, 1);
      throw e;
    })
  );

  let e = await gotError;
  assert_true(e instanceof DOMException);
  assert_equals(e.name, 'EncodingError');
  assert_equals(decoder.state, 'closed', 'state');
}, 'Decode empty frame');


promise_test(async t => {
  await checkImplements();
  const callbacks = {};

  let errors = 0;
  let gotError = new Promise(resolve => callbacks.error = e => {
    errors++;
    resolve(e);
  });

  let outputs = 0;
  callbacks.output = frame => {
    outputs++;
    frame.close();
  };

  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);  // Decode keyframe first.
  decoder.decode(createCorruptChunk(2));

  await promise_rejects_dom(t, "EncodingError",
    decoder.flush().catch((e) => {
      assert_equals(errors, 1);
      throw e;
    })
  );

  assert_less_than_equal(outputs, 1);
  let e = await gotError;
  assert_true(e instanceof DOMException);
  assert_equals(e.name, 'EncodingError');
  assert_equals(decoder.state, 'closed', 'state');
}, 'Decode corrupt frame');

promise_test(async t => {
  await checkImplements();
  const decoder = createVideoDecoder(t);

  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);  // Decode keyframe first.
  decoder.decode(createCorruptChunk(1));

  let flushDone = decoder.flush();
  decoder.close();

  // Flush should have been synchronously rejected, with no output() or error()
  // callbacks.
  await promise_rejects_dom(t, 'AbortError', flushDone);
}, 'Close while decoding corrupt frame');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);

  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);

  let outputs = 0;
  callbacks.output = frame => {
    outputs++;
    frame.close();
  };

  await decoder.flush();
  assert_equals(outputs, 1, 'outputs');

  decoder.decode(CHUNKS[0]);
  await decoder.flush();
  assert_equals(outputs, 2, 'outputs');
}, 'Test decoding after flush');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);

  decoder.configure(CONFIG);
  decoder.decode(new EncodedVideoChunk(
      {type: 'key', timestamp: -42, data: CHUNK_DATA[0]}));

  let outputs = 0;
  callbacks.output = frame => {
    outputs++;
    assert_equals(frame.timestamp, -42, 'timestamp');
    frame.close();
  };

  await decoder.flush();
  assert_equals(outputs, 1, 'outputs');
}, 'Test decoding a with negative timestamp');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);

  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);
  decoder.decode(CHUNKS[1]);
  const flushDone = decoder.flush();

  // Wait for the first output, then reset.
  let outputs = 0;
  await new Promise(resolve => {
    callbacks.output = frame => {
      outputs++;
      assert_equals(outputs, 1, 'outputs');
      decoder.reset();
      frame.close();
      resolve();
    };
  });

  // Flush should have been synchronously rejected.
  await promise_rejects_dom(t, 'AbortError', flushDone);

  assert_equals(outputs, 1, 'outputs');
}, 'Test reset during flush');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);

  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);
  const flushDone = decoder.flush();

  let flushDoneInCallback;
  let outputs = 0;
  await new Promise(resolve => {
    callbacks.output = frame => {
      decoder.reset();
      frame.close();

      callbacks.output = frame => {
        outputs++;
        frame.close();
      };
      callbacks.error = e => {
        t.unreached_func('unexpected error()');
      };
      decoder.configure(CONFIG);
      decoder.decode(CHUNKS[0]);
      flushDoneInCallback = decoder.flush();

      resolve();
    };
  });

  // First flush should have been synchronously rejected.
  await promise_rejects_dom(t, 'AbortError', flushDone);
  // Wait for the second flush and check the output count.
  await flushDoneInCallback;
  assert_equals(outputs, 1, 'outputs');
}, 'Test new flush after reset in a flush callback');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);

  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);
  const flushDone = decoder.flush();
  let flushDoneInCallback;

  await new Promise(resolve => {
    callbacks.output = frame => {
      decoder.reset();
      frame.close();

      callbacks.output = frame => { frame.close(); };
      decoder.configure(CONFIG);
      decoder.decode(CHUNKS[0]);
      decoder.decode(createCorruptChunk(1));
      flushDoneInCallback = decoder.flush();

      resolve();
    };
  });

  // First flush should have been synchronously rejected.
  await promise_rejects_dom(t, 'AbortError', flushDone);
  // Wait for the second flush and check the error in the rejected promise.
  await promise_rejects_dom(t, 'EncodingError', flushDoneInCallback);
}, 'Test decoding a corrupt frame after reset in a flush callback');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);

  decoder.configure({...CONFIG, optimizeForLatency: true});
  decoder.decode(CHUNKS[0]);

  // The frame should be output without flushing.
  await new Promise(resolve => {
    callbacks.output = frame => {
      frame.close();
      resolve();
    };
  });
}, 'Test low-latency decoding');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  callbacks.output = frame => { frame.close(); };
  const decoder = createVideoDecoder(t, callbacks);

  // No decodes yet.
  assert_equals(decoder.decodeQueueSize, 0);

  decoder.configure(CONFIG);

  // Still no decodes.
  assert_equals(decoder.decodeQueueSize, 0);

  let lastDequeueSize = Infinity;
  decoder.ondequeue = () => {
    assert_greater_than(lastDequeueSize, 0, "Dequeue event after queue empty");
    assert_greater_than(lastDequeueSize, decoder.decodeQueueSize,
                        "Dequeue event without decreased queue size");
    lastDequeueSize = decoder.decodeQueueSize;
  };

  for (let chunk of CHUNKS)
    decoder.decode(chunk);

  assert_greater_than_equal(decoder.decodeQueueSize, 0);
  assert_less_than_equal(decoder.decodeQueueSize, CHUNKS.length);

  await decoder.flush();
  // We can guarantee that all decodes are processed after a flush.
  assert_equals(decoder.decodeQueueSize, 0);
  // Last dequeue event should fire when the queue is empty.
  assert_equals(lastDequeueSize, 0);

  // Reset this to Infinity to track the decline of queue size for this next
  // batch of decodes.
  lastDequeueSize = Infinity;

  for (let chunk of CHUNKS)
    decoder.decode(chunk);

  assert_greater_than_equal(decoder.decodeQueueSize, 0);
  decoder.reset();
  assert_equals(decoder.decodeQueueSize, 0);
}, 'VideoDecoder decodeQueueSize test');

promise_test(async t => {
  await checkImplements();
  const callbacks = {};
  const decoder = createVideoDecoder(t, callbacks);
  decoder.configure(CONFIG);
  decoder.reset();
  decoder.configure(CONFIG);
  decoder.decode(CHUNKS[0]);

  let outputs = 0;
  callbacks.output = frame => {
    outputs++;
    assert_equals(frame.timestamp, CHUNKS[0].timestamp, 'timestamp');
    assert_equals(frame.duration, CHUNKS[0].duration, 'duration');
    frame.close();
  };

  await decoder.flush();
  assert_equals(outputs, 1, 'outputs');
}, 'Test configure, reset, configure does not stall');
