w3c / webcodecs

WebCodecs is a flexible web API for encoding and decoding audio and video.
https://w3c.github.io/webcodecs/
Other
939 stars 132 forks source link

Fatal encoding/decoding error on Windows 10/11 #748

Closed konstantin-paulus closed 7 months ago

konstantin-paulus commented 7 months ago

I'm trying to encode/decode a large amount of frames using the canvas and webcodecs api. This works fine on MacOs (Chrome), but when I run the same code on Windows (also Chrome) the browser window turns black, minimizes and maximizes again after encoding/decoding a few hundred frames. This also halts the execution of all functions.

It can be replicated with just the encoding part using the following code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
  </head>
  <body>
    <h1>💖 Hello World!</h1>
    <button id="encoder-btn">Start Encoding</button>
  </body>
  <script>
    var settings = {
      height: 1920,
      width: 1080,
      totalFrames: 2 * 60 * 30, // 2 min
      fps: 30,
    };

    const profile = {
      codec: "avc1.640C32",
      hardwareAcceleration: "prefer-hardware",
      width: 1920,
      height: 1080,
      bitrate: 2e6, // 5 Mbps
      bitrateMode: "constant",
      framerate: 30,
    };

    document
      .getElementById("encoder-btn")
      .addEventListener("click", async () => {
        var canvas = new OffscreenCanvas(settings.width, settings.height);
        var ctx = canvas.getContext("2d");

        var encoder = new VideoEncoder({
          output: () => null,
          error: console.log,
        });
        encoder.configure(profile);

        var duration = Math.floor(1 / settings.fps);

        for (var frame = 0; frame <= settings.totalFrames; frame++) {
          if (frame % settings.fps == 0) {
            console.log(Math.round((frame * 100) / settings.totalFrames) + "%");
          }

          ctx.clearRect(0, 0, settings.width, settings.height);
          ctx.fillStyle = "white";
          ctx.fillRect(0, 0, settings.width, settings.height);
          ctx.fillStyle = "red";
          ctx.fillRect(
            frame % (settings.width - 100),
            frame % (settings.height - 100),
            100,
            100
          );

          var videoFrame = new VideoFrame(canvas, {
            timestamp: Math.floor((frame / settings.fps) * 1e6),
            duration,
          });
          encoder.encode(videoFrame, { keyFrame: frame % (5 * settings.fps) == 0 });
          videoFrame.close();
        }

        await encoder.flush();

        console.log('DONE!!!')
      });
  </script>
</html>

If you open up the console it should log DONE!!! after encoding all frames but it never does. In some cases it displays the error DOMException: Encoding error. or DOMException: Decoding error..

Now if you decrease the totalFrames from 2 * 60 * 30 to 10 * 30 the error doesn't appear. This is also the case with a smaller canvas (width & height).

The Browser version that I've experienced this on is Version 119.0.6045.160 (Official Build) (64-bit)

padenot commented 7 months ago

This sounds like an implementation bug, please file a bug in the vendor's bug tracker at https://new.crbug.com/ (Google account needed), this tracker is for the specification of the Web Codecs API, not a particular implementation in a browser.

The snippet to reproduce is usually very appreciated by browser folks, but I'm sure the Chromium developers there will need information about your computer, such as its CPU / GPU (the thing that does the hardware encoding), and the graphics driver version. To me, it smells like an over-use of graphics resources.

cc @Djuffin for Chromium.

konstantin-paulus commented 7 months ago

This sounds like an implementation bug, please file a bug in the vendor's bug tracker at https://new.crbug.com/ (Google account needed), this tracker is for the specification of the Web Codecs API, not a particular implementation in a browser.

The snippet to reproduce is usually very appreciated by browser folks, but I'm sure the Chromium developers there will need information about your computer, such as its CPU / GPU (the thing that does the hardware encoding), and the graphics driver version. To me, it smells like an over-use of graphics resources.

cc @Djuffin for Chromium.

For reference: https://bugs.chromium.org/p/chromium/issues/detail?id=1504122