diff options
Diffstat (limited to 'media/test/data/blackwhite.html')
-rw-r--r-- | media/test/data/blackwhite.html | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/media/test/data/blackwhite.html b/media/test/data/blackwhite.html new file mode 100644 index 0000000..6b9d049 --- /dev/null +++ b/media/test/data/blackwhite.html @@ -0,0 +1,231 @@ +<!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', + 'yuvj420p.mp4', + 'yuv422p.mp4', + 'yuv444p.mp4', + 'yuv420p.avi' + ]; + + 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) { + if (Math.abs(imgData[(x + y * stride) * 4 + i] - expected) > + allowedError) { + 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> |