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
  141
  142
  143
  144
  145
  146

content / test / data / gpu / webcodecs / svc.html [blame]

<!DOCTYPE html>
<!--
Check hardware accelerated scalable video coding and decoding after dropping
some chunks.
-->
<html>

<head>
  <title>SVC encoding test</title>
  <script src="webcodecs_common.js"></script>
  <script type="text/javascript">
    'use strict';
    async function main(arg) {
      const width = 640;
      const height = 480;
      const frames_to_encode = 32;
      let frames_encoded = 0;
      let frames_decoded = 0;
      let errors = 0;
      const base_layer_decimator = ([null, null, 2, 4])[arg.layers];
      let expected_dot_count = [];

      const encoder_config = {
        codec: arg.codec,
        hardwareAcceleration: arg.acceleration,
        width: width,
        height: height,
        bitrate: 2000000,
        scalabilityMode: "L1T" + arg.layers,
        latencyMode: "realtime",
      };

      TEST.log('Starting test with arguments: ' + JSON.stringify(arg));
      let supported = false;
      try {
        supported = (await VideoEncoder.isConfigSupported(encoder_config)).supported;
      } catch (e) {}
      if (!supported) {
        TEST.skip('Unsupported codec: ' + arg.codec);
        return;
      }

      let decoder = new VideoDecoder({
        output(frame) {
          frames_decoded++;
          let dots = expected_dot_count.shift();
          // Check that we have intended number of dots and no more.
          // Completely black frame shouldn't pass the test.
          if(!validateBlackDots(frame, dots) ||
            validateBlackDots(frame, dots + 1)) {
            TEST.reportFailure(
                `Unexpected dot count ts:${frame.timestamp} dots:${dots}`);
          }

          frame.close();
        },
        error(e) {
          errors++;
          TEST.log(e);
        }
      });

      const encoder_init = {
        output(chunk, metadata) {
          let config = metadata.decoderConfig;
          if (config) {
            decoder.configure(config);
          }

          frames_encoded++;
          TEST.assert(metadata.svc != null);
          TEST.assert(metadata.svc.temporalLayerId < arg.layers,
                      "too large temporal ID");
          if (metadata.svc.temporalLayerId == 0) {
            decoder.decode(chunk);
          }
        },
        error(e) {
          errors++;
          TEST.log(e);
        }
      };

      let encoder = new VideoEncoder(encoder_init);
      encoder.configure(encoder_config);
      let source = new CanvasSource(width, height);

      for (let i = 0; i < frames_to_encode; i++) {
        let frame = await source.getNextFrame();
        encoder.encode(frame, { keyFrame: false });
        if (i % base_layer_decimator == 0)
          expected_dot_count.push(i);
        frame.close();

        await waitForNextFrame();
      }
      await encoder.flush();
      await decoder.flush();
      encoder.close();
      decoder.close();
      source.close();

      TEST.assert(
        frames_encoded == frames_to_encode,
        'frames_encoded mismatch: ' + frames_encoded);

      let base_layer_frames = frames_encoded / base_layer_decimator;
      TEST.assert(
        frames_decoded == base_layer_frames,
        'frames_decoded mismatch: ' + frames_decoded);
      TEST.assert(
        errors == 0, 'Decoding or encoding errors occurred during the test');
      TEST.log('Test completed');
    }
    addManualTestButton([{
      'codec': 'avc1.42001E',
      'acceleration': 'prefer-software',
      'layers': 2
    },
    {
      'codec': 'avc1.42001E',
      'acceleration': 'prefer-hardware',
      'layers': 2
    },
    {
      'codec': 'hvc1.1.6.L123.00',
      'acceleration': 'prefer-software',
      'layers': 2
    },
    {
      'codec': 'hvc1.1.6.L123.00',
      'acceleration': 'prefer-hardware',
      'layers': 2
    },
    {
      'codec': 'av01.0.04M.08',
      'acceleration': 'prefer-software',
      'layers': 2
    }]);
  </script>
</head>

<body>
</body>

</html>