// META: global=window,dedicatedworker
// META: script=/webcodecs/video-encoder-utils.js
// META: variant=?av1
// META: variant=?vp8
// META: variant=?vp9_p0
// META: variant=?vp9_p2
// META: variant=?h264_avc
// META: variant=?h264_annexb

var ENCODER_CONFIG = null;
promise_setup(async () => {
  const config = {
    '?av1': {codec: 'av01.0.04M.08'},
    '?vp8': {codec: 'vp8'},
    '?vp9_p0': {codec: 'vp09.00.10.08'},
    '?vp9_p2': {codec: 'vp09.02.10.10'},
    '?h264_avc': {codec: 'avc1.42001E', avc: {format: 'avc'}},
    '?h264_annexb': {codec: 'avc1.42001E', avc: {format: 'annexb'}}
  }[location.search];
  config.hardwareAcceleration = 'prefer-software';
  config.bitrateMode = "constant";
  config.scalabilityMode = "L1T2";
  config.framerate = 30;
  ENCODER_CONFIG = config;
});

promise_test(async t => {
  let original_w = 800;
  let original_h = 600;
  let original_bitrate = 3_000_000;

  let new_w = 640;
  let new_h = 480;
  let new_bitrate = 2_000_000;

  let next_ts = 0
  let reconf_ts = 0;
  let frames_to_encode = 16;
  let before_reconf_frames = 0;
  let after_reconf_frames = 0;

  let process_video_chunk = function (chunk, metadata) {
    let config = metadata.decoderConfig;
    var data = new Uint8Array(chunk.data);
    assert_greater_than_equal(data.length, 0);
    let after_reconf = (reconf_ts != 0) && (chunk.timestamp >= reconf_ts);
    if (after_reconf) {
      after_reconf_frames++;
      if (config) {
        assert_equals(config.codedWidth, new_w);
        assert_equals(config.codedHeight, new_h);
      }
    } else {
      before_reconf_frames++;
      if (config) {
        assert_equals(config.codedWidth, original_w);
        assert_equals(config.codedHeight, original_h);
      }
    }
  };

  const init = {
    output: (chunk, md) => {
      try {
        process_video_chunk(chunk, md);
      } catch (e) {
        assert_unreached(e.message);
      }
    },
    error: (e) => {
      assert_unreached(e.message);
    },
  };
  const params = {
    ...ENCODER_CONFIG,
    width: original_w,
    height: original_h,
    bitrate: original_bitrate,
  };
  await checkEncoderSupport(t, params);

  let encoder = new VideoEncoder(init);
  encoder.configure(params);

  // Remove this flush after crbug.com/1275789 is fixed
  await encoder.flush();

  // Encode |frames_to_encode| frames with original settings
  for (let i = 0; i < frames_to_encode; i++) {
    var frame = createFrame(original_w, original_h, next_ts++);
    encoder.encode(frame, {});
  }

  params.width = new_w;
  params.height = new_h;
  params.bitrate = new_bitrate;

  // Reconfigure encoder and run |frames_to_encode| frames with new settings
  encoder.configure(params);
  reconf_ts = next_ts;

  for (let i = 0; i < frames_to_encode; i++) {
    var frame = createFrame(new_w, new_h, next_ts++);
    encoder.encode(frame, {});
  }

  await encoder.flush();

  // Configure back to original config
  params.width = original_w;
  params.height = original_h;
  params.bitrate = original_bitrate;
  encoder.configure(params);
  await encoder.flush();

  encoder.close();
  assert_equals(before_reconf_frames, frames_to_encode);
  assert_equals(after_reconf_frames, frames_to_encode);
}, "Reconfiguring encoder");
