<!-- This was created from the demo of webcodecs-blogpost-demo.glitch.me, and added the webgl support for test only purpose. -->

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta http-equiv="origin-trial"
    content="AoSY6Q4OOuuZVXTqOwJlfk4n77EL0esumtLRHj+9V97JoFfLq4AKsWlza8A8HmxTx1PU7SSzpjWK6F62bwWLPQYAAAB3eyJvcmlnaW4iOiJodHRwczovL3dlYmNvZGVjcy1ibG9ncG9zdC1kZW1vLmdsaXRjaC5tZTo0NDMiLCJmZWF0dXJlIjoiV2ViQ29kZWNzIiwiZXhwaXJ5IjoxNjA1NDc0OTQ4LCJpc1N1YmRvbWFpbiI6dHJ1ZX0=">
  <title>WebCodecs API demo: Encoding and Decoding</title>
  <style>
    canvas {
      padding: 10px;
      background: gold;
    }

    button {
      background-color: #555555;
      border: none;
      color: white;
      padding: 15px 32px;
      width: 150px;
      text-align: center;
      display: block;
      font-size: 16px;
    }
  </style>
  <script src="../../../../extensions/proposals/WEBGL_webcodecs_video_frame/webgl_webcodecs_video_frame.js"></script>
</head>

<body>
  <canvas id="src" width="640" height="480"></canvas>
  <button onclick="playPause()">Pause</button>
  <canvas id="dst" width="640" height="480"></canvas>
  <script>
    let codec_string = "vp8";
    let keep_going = true;

    function playPause() {
      keep_going = !keep_going;
      let btn = document.querySelector("button");
      if (keep_going) {
        btn.innerText = "Pause";
      } else {
        btn.innerText = "Play";
      }
    }

    async function startDrawing() {
      let cnv = document.getElementById("src");
      var ctx = cnv.getContext('2d', { alpha: false });

      ctx.fillStyle = "white";
      let width = cnv.width;
      let height = cnv.height;
      let cx = width / 2;
      let cy = height / 2;
      let r = Math.min(width, height) / 5;
      let drawOneFrame = function (time) {
        let angle = Math.PI * 2 * (time / 5000);
        let scale = 1 + 0.3 * Math.sin(Math.PI * 2 * (time / 7000));
        ctx.save();
        ctx.fillRect(0, 0, width, height);

        ctx.translate(cx, cy);
        ctx.rotate(angle);
        ctx.scale(scale, scale);

        ctx.font = '30px Verdana';
        ctx.fillStyle = 'black';
        const text = "😊📹📷Hello WEBGL_webcodecs_video_frame🎥🎞️😊";
        const size = ctx.measureText(text).width;
        ctx.fillText(text, -size / 2, 0);
        ctx.restore();
        window.requestAnimationFrame(drawOneFrame);
      }
      window.requestAnimationFrame(drawOneFrame);
    }

    function captureAndEncode(processChunk) {
      let cnv = document.getElementById("src");
      let fps = 30;
      let pending_outputs = 0;
      let frame_counter = 0;
      let stream = cnv.captureStream(fps);
      let processor = new MediaStreamTrackProcessor(stream.getVideoTracks()[0]);

      const init = {
        output: (chunk) => {
          pending_outputs--;
          processChunk(chunk);
        },
        error: (e) => {
          console.log(e.message);
          vtr.stop();
        }
      };

      const config = {
        codec: codec_string,
        width: cnv.width,
        height: cnv.height,
        bitrate: 10e6,
        framerate: fps,
      };

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

      const frame_reader = processor.readable.getReader();
      frame_reader.read().then(function processFrame({done, value}) {
        if (done)
          return;

        if (pending_outputs > 30) {
          // Too many frames in flight, encoder is overwhelmed
          // let's drop this frame.
          value.close();
          frame_reader.read().then(processFrame);
          return;
        }

        if(!keep_going) {
          value.close();
          frame_reader.read().then(processFrame);
          return;
        }

        frame_counter++;
        pending_outputs++;
        const insert_keyframe = (frame_counter % 150) == 0;
        encoder.encode(value, { keyFrame: insert_keyframe });

        frame_reader.read().then(processFrame);
      });
    }


    function startDecodingAndRendering(cnv, handleFrame) {

      const init = {
        output: handleFrame,
        error: (e) => {
          console.log(e.message);
        }
      };

      const config = {
        codec: codec_string,
        codedWidth: cnv.width,
        codedHeight: cnv.height
      };

      let decoder = new VideoDecoder(init);
      decoder.configure(config);
      return decoder;
    }


    function main() {
      if (!("VideoEncoder" in window)) {
        document.body.innerHTML = "<h1>WebCodecs API is not supported.</h1>";
        return;
      }

      let cnv = document.getElementById("dst");
      let handleFrame = requestWebGLVideoFrameHandler(cnv);
      if (handleFrame === null) {
        document.body.innerHTML =
          "<h1>Unable to request WebGL to render video frames.</h1>";
        return;
      }

      startDrawing();
      let decoder = startDecodingAndRendering(cnv, handleFrame);
      captureAndEncode((chunk) => {
        decoder.decode(chunk);
      });
    }

    document.body.onload = main;
  </script>

</body>

</html>