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

content / test / data / gpu / webcodecs / frame-size-change.js [blame]

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

async function main(arg) {
  // Reduce frame size first, then increase frame size. The last item is the
  // largest frame size, which will be used for creating source.
  const frame_size_params = [
    {
      width: 320,
      height: 240,
      bitrate: 500_000,
    },
    {
      width: 160,
      height: 120,
      bitrate: 300_000,
    },
    {
      width: FRAME_WIDTH,
      height: FRAME_HEIGHT,
      bitrate: 800_000,
    }
  ];
  const frames_in_one_pass = 10;
  let errors = 0;
  let decoder_param_index = 0;
  let output_trunks = 0;

  let source = await createFrameSource(
      arg.source_type, frame_size_params[frame_size_params.length - 1].width,
      frame_size_params[frame_size_params.length - 1].height);
  if (!source) {
    TEST.skip('Unsupported source: ' + arg.source_type);
    return;
  }

  const init = {
    output(chunk, metadata) {
      TEST.assert(decoder_param_index < frame_size_params.length);
      if (metadata.decoderConfig) {
        TEST.assert(
            output_trunks == 0,
            'metadata.decoderConfig is only available for the first frame ' +
                'after configuration change.');
        // Some platform requires 16x16 alignment.
        TEST.assert(
            metadata.decoderConfig.codedWidth >=
                    frame_size_params[decoder_param_index].width - 16 &&
                metadata.decoderConfig.codedWidth <=
                    frame_size_params[decoder_param_index].width + 16,
            'Unexpected codedWidth.');
        TEST.assert(
            metadata.decoderConfig.codedHeight >=
                    frame_size_params[decoder_param_index].height - 16 &&
                metadata.decoderConfig.codedHeight <=
                    frame_size_params[decoder_param_index].height + 16,
            'Unexpected codedHeight.');
      }
      output_trunks++;
      if (output_trunks == frames_in_one_pass) {
        decoder_param_index++;
        output_trunks = 0;
      }
    },
    error(e) {
      errors++;
      TEST.log(e);
    }
  };

  let encoder = new VideoEncoder(init);
  for (const param of frame_size_params) {
    const encoder_config = {
      ...param,
      codec: arg.codec,
      acceleration: 'prefer-hardware',
    };

    let supported = false;
    try {
      supported =
          (await VideoEncoder.isConfigSupported(encoder_config)).supported;
    } catch (e) {
      TEST.assert(
          false, 'Failed to check if the given configuration is supported.');
    }
    if (!supported) {
      TEST.skip('Unsupported configuration: ' + JSON.stringify(encoder_config));
      return;
    }
    encoder.configure(encoder_config);
    for (let i = 0; i < frames_in_one_pass; i++) {
      let frame = await source.getNextFrame();
      encoder.encode(frame);
      frame.close();
      await waitForNextFrame();
    }
  }

  await encoder.flush();
  encoder.close();
  source.close();

  TEST.assert(
      decoder_param_index == frame_size_params.length,
      `Decoder config should be changed ${frame_size_params.length} times.`);
  TEST.assert(
      output_trunks == 0,
      `Decoder should output ${
          frames_in_one_pass} frames for the last config.`);
  TEST.assert(errors == 0, 'Encoding errors occurred during the test');
  TEST.log('Test completed');
}