<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        color: white;
        background-color: black;
      }
    </style>
  </head>
  <body onload="main()">
    <div id="buttons"></div>
    <table>
      <tr>
        <td>Image</td>
        <td id="video_header"></td>
        <td>Absolute Diff</td>
        <td>Different Pixels</td>
      </tr>
      <tr>
        <td><img src="blackwhite.png"></div>
        <td><video autoplay></video></div>
        <td><canvas id="diff"></canvas></td>
        <td><canvas id="mask"></canvas></td>
      </tr>
    </div>

    <p id="result"></p>

    <script>
      function log(str) {
        document.getElementById('result').textContent = str;
        console.log(str);
      }

      function loadVideo(name) {
        var videoElem = document.querySelector('video');
        videoElem.src = 'blackwhite_' + name;

        document.getElementById('video_header').textContent = name;
        videoElem.addEventListener('ended', onVideoEnded);
      }

      function onVideoEnded(e) {
        document.title = verifyVideo() ? 'ENDED' : 'FAILED';
      }

      function onVideoError(e) {
        document.title = 'ERROR';
        document.getElementById('diff').style.visibility = 'hidden';
        document.getElementById('mask').style.visibility = 'hidden';
        log('Error playing video: ' + e.target.error.code + '.');
      }

      function main() {
        // Programatically create buttons for each clip for manual testing.
        var buttonsElem = document.getElementById('buttons');

        function createButton(name) {
          var buttonElem = document.createElement('button');
          buttonElem.textContent = name;
          buttonElem.addEventListener('click', function() {
            loadVideo(name);
          });
          buttonsElem.appendChild(buttonElem);
        }

        var VIDEOS = [
          'yuv420p.ogv',
          'yuv422p.ogv',
          'yuv444p.ogv',
          'yuv420p.webm',
          'yuv444p.webm',
          'yuv420p.mp4',
          'yuv420p_rec709.mp4',
          'yuvj420p.mp4',
          'yuv422p.mp4',
          'yuv444p.mp4',
          'yuv420p.avi',
          'yuv420p_hi10p.mp4'
        ];

        for (var i = 0; i < VIDEOS.length; ++i) {
          createButton(VIDEOS[i]);
        }

        // Video event handlers.
        var videoElem = document.querySelector('video');
        videoElem.addEventListener('error', onVideoError);

        // Check if a query parameter was provided for automated tests.
        if (window.location.search.length > 1) {
          loadVideo(window.location.search.substr(1));
        } else {
          // If we're not an automated test, compute some pretty diffs.
          document.querySelector('video').addEventListener('ended',
                                                           computeDiffs);
        }
      }

      function getCanvasPixels(canvas) {
        try {
          return canvas.getContext('2d')
              .getImageData(0, 0, canvas.width, canvas.height)
              .data;
        } catch(e) {
          var message = 'ERROR: ' + e;
          if (e.name == 'SecurityError') {
            message += ' Couldn\'t get image pixels, try running with ' +
                       '--allow-file-access-from-files.';
          }
          log(message);
        }
      }

      function verifyVideo() {
        var videoElem = document.querySelector('video');
        var offscreen = document.createElement('canvas');
        offscreen.width = videoElem.videoWidth;
        offscreen.height = videoElem.videoHeight;
        offscreen.getContext('2d').drawImage(videoElem, 0, 0, offscreen.width,
                                             offscreen.height);

        videoData = getCanvasPixels(offscreen);
        if (!videoData)
          return false;

        // Check the color of a givel pixel |x,y| in |imgData| against an
        // expected value, |expected|, with up to |allowedError| difference.
        function checkColor(imgData, x, y, stride, expected, allowedError) {
          for (var i = 0; i < 3; ++i) {
            var actual = imgData[(x + y * stride) * 4 + i];
            if (Math.abs(actual - expected) > allowedError) {
              log('Color didn\'t match at (' + x + ', ' + y + '). Expected: ' +
                  expected + ', actual: ' + actual);
              return false;
            }
          }
          return true;
        }

        // Check one pixel in each quadrant (in the upper left, away from
        // boundaries and the text, to avoid compression artifacts).
        // Also allow a small error, for the same reason.

        // TODO(mtomasz): Once code.google.com/p/libyuv/issues/detail?id=324 is
        // fixed, the allowedError should be decreased to 1.
        var allowedError = 2;

        return checkColor(videoData, 30, 30, videoElem.videoWidth, 0xff,
                          allowedError) &&
               checkColor(videoData, 150, 30, videoElem.videoWidth, 0x00,
                          allowedError) &&
               checkColor(videoData, 30, 150, videoElem.videoWidth, 0x10,
                          allowedError) &&
               checkColor(videoData, 150, 150, videoElem.videoWidth, 0xef,
                          allowedError);
      }

      // Compute a standard diff image, plus a high-contrast mask that shows
      // each differing pixel more visibly.
      function computeDiffs() {
        var diffElem = document.getElementById('diff');
        var maskElem = document.getElementById('mask');
        var videoElem = document.querySelector('video');
        var imgElem = document.querySelector('img');

        var width = imgElem.width;
        var height = imgElem.height;

        if (videoElem.videoWidth != width || videoElem.videoHeight != height) {
          log('ERROR: video dimensions don\'t match reference image ' +
              'dimensions');
          return;
        }

        // Make an offscreen canvas to dump reference image pixels into.
        var offscreen = document.createElement('canvas');
        offscreen.width = width;
        offscreen.height = height;

        offscreen.getContext('2d').drawImage(imgElem, 0, 0, width, height);
        imgData = getCanvasPixels(offscreen);
        if (!imgData)
          return;

        // Scale and clear diff canvases.
        diffElem.width = maskElem.width = width;
        diffElem.height = maskElem.height = height;
        var diffCtx = diffElem.getContext('2d');
        var maskCtx = maskElem.getContext('2d');
        maskCtx.clearRect(0, 0, width, height);
        diffCtx.clearRect(0, 0, width, height);

        // Copy video pixels into diff.
        diffCtx.drawImage(videoElem, 0, 0, width, height);

        var diffIData = diffCtx.getImageData(0, 0, width, height);
        var diffData = diffIData.data;
        var maskIData = maskCtx.getImageData(0, 0, width, height);
        var maskData = maskIData.data;

        // Make diffs and collect stats.
        var meanSquaredError = 0;
        for (var i = 0; i < imgData.length; i += 4) {
          var difference = 0;
          for (var j = 0; j < 3; ++j) {
            diffData[i + j] = Math.abs(diffData[i + j] - imgData[i + j]);
            meanSquaredError += diffData[i + j] * diffData[i + j];
            if (diffData[i + j] != 0) {
              difference += diffData[i + j];
            }
          }
          if (difference > 0) {
            if (difference <= 3) {
              // If we're only off by a bit per channel or so, use darker red.
              maskData[i] = 128;
            } else {
              // Bright red to indicate a different pixel.
              maskData[i] = 255;
            }
            maskData[i+3] = 255;
          }
        }

        meanSquaredError /= width * height;
        log('Mean squared error: ' + meanSquaredError);
        diffCtx.putImageData(diffIData, 0, 0);
        maskCtx.putImageData(maskIData, 0, 0);
        document.getElementById('diff').style.visibility = 'visible';
        document.getElementById('mask').style.visibility = 'visible';
      }
    </script>
  </body>
</html>
