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

content / test / data / media / canvas_capture.html [blame]

<!DOCTYPE html>
<html>
<head>
<title>Media Capture from Canvas Browser Test</title>
</head>
<body>
  <div> Capture and playback from canvas elements.</div>
</body>
<script type="text/javascript" src="webrtc_test_utilities.js"></script>
<script>

'use strict';

const NUMBER_OF_EVENTS_TO_RECORD = 15;
const ON_DATA_AVAILABLE_THRESHOLD = 10;
// We might have a long time drift due to blocked threads, see
// https://crbug.com/916928.
const TIME_DRIFT_ALLOWED_IN_MS = 10;

function checkForRedraw(canvas, drawCounter, drawFunction) {
  if (++drawCounter <= NUMBER_OF_EVENTS_TO_RECORD) {
    requestAnimationFrame(function(timestamp) {
      redraw(canvas, drawCounter, drawFunction, timestamp);
    });
  }
}

function redraw(canvas, drawCounter, drawFunction, timestamp) {
  if (performance.now() - timestamp > TIME_DRIFT_ALLOWED_IN_MS) {
    console.log("Drifted too much, draw again");
    drawCounter--;
  }
  drawFunction(canvas, drawCounter)
}

function draw2d(canvas, drawCounter) {
  var ctx = canvas.getContext('2d');
  ctx.fillStyle = 'green';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  checkForRedraw(canvas, drawCounter, draw2d);
};

function drawWebGL(canvas, drawCounter) {
  var gl = canvas.getContext('webgl');
  gl.clearColor(0, 1, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  checkForRedraw(canvas, drawCounter, drawWebGL);
};

function drawOffscreenCanvas(canvas, drawCounter) {
  var ctx = canvas.getContext('2d');
  ctx.fillStyle = 'green';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  checkForRedraw(canvas, drawCounter, drawOffscreenCanvas);
};

function drawBitmapRenderer(canvas, drawCounter) {
  var gl = canvas.getContext('bitmaprenderer');
  var offscreen = new OffscreenCanvas(canvas.width, canvas.height);
  var ctx = offscreen.getContext('2d');
  ctx.fillStyle = 'green';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  gl.transferFromImageBitmap(offscreen.transferToImageBitmap());
  checkForRedraw(canvas, drawCounter, drawBitmapRenderer);
};

async function testCanvasCapture(drawFunction) {
  var canvas = document.createElement('canvas');
  canvas.width = canvas.height = 64;

  var stream = canvas.captureStream();
  assertTrue(stream, 'Error creating MediaStream');
  assertEquals(1, stream.getVideoTracks().length);
  assertEquals(0, stream.getAudioTracks().length);

  var recorded_events = 0;
  const recorder = new MediaRecorder(stream);
  assertTrue(recorder, 'Error creating recorder out of the MediaStream');

  const completePromise = new Promise(resolve => {
    recorder.ondataavailable = function(event) {
      if (event.data.size > ON_DATA_AVAILABLE_THRESHOLD) {
        if (++recorded_events == NUMBER_OF_EVENTS_TO_RECORD)
          resolve();
      }
    };
  });

  recorder.start(0);
  if (drawFunction.toString() == drawOffscreenCanvas.toString()) {
    var offscreen = canvas.transferControlToOffscreen();
    drawFunction(offscreen, 0);
  } else {
    drawFunction(canvas, 0);
  }

  return completePromise
    .then(logSuccess);
}

</script>
</body>
</html>