<!doctype html><!-- webkit-test-runner [ WebRTCRemoteVideoFrameEnabled=true ] -->
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing video rotation in basic video exchange </title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
    </head>
    <body>
        <video id="localVideo" autoplay playsInline width="320" height="240"></video>
        <video id="remoteVideo" autoplay playsInline width="320" height="240"></video>
        <canvas id="canvas0" width="320" height="240"></canvas>
        <canvas id="canvas1" width="320" height="240"></canvas>
        <canvas id="canvas2" width="320" height="240"></canvas>
        <canvas id="canvas3" width="320" height="240"></canvas>
        <script src ="routines.js"></script>
        <script>
function isVideoBlack(video, canvasId)
{
    var canvas = document.getElementById(canvasId);
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

    imageData = canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);
    data = imageData.data;
    for (var cptr = 0; cptr < canvas.width * canvas.height; ++cptr) {
        // Approximatively black pixels.
        if (data[4 * cptr] > 30 || data[4 * cptr + 1] > 30 || data[4 * cptr + 2] > 30)
            return false;
    }
    return true;
}

function pollVideoBlackCheck(expected, video, canvasId, resolve)
{
    if (isVideoBlack(video, canvasId) === expected) {
        resolve();
        return;
    }

    setTimeout(() => pollVideoBlackCheck(expected, video, canvasId, resolve), 100);
}

function checkVideoBlack(expected, video, canvasId)
{
    return new Promise((resolve, reject) => {
        pollVideoBlackCheck(expected, video, canvasId, resolve);
        setTimeout(() => reject("checkVideoBlack timed out for '" + canvasId + "', expected " + expected), 5000);
    });
}

async function waitForTrackRotation(track, angle, counter)
{
    if (!window.internals)
        return;

    if (!counter) {
        internals.observeMediaStreamTrack(track);
        counter = 1;
    }

    await new Promise(resolve => setTimeout(resolve, 50));
    const value = await internals.mediaStreamTrackVideoFrameRotation()
    if (angle === value)
        return;    

    if (++counter > 50)
        return Promise.reject("waitForTrackRotation timed out with value " + value + " while expecting " + angle);

    return waitForTrackRotation(track, angle, counter);
}

var track;
promise_test((test) => {
    if (window.testRunner)
        testRunner.setUserMediaPermission(true);

    return navigator.mediaDevices.getUserMedia({video: {width: 320, height: 240, facingMode: "environment"}}).then((localStream) => {
        localVideo.srcObject = localStream;
        return new Promise((resolve, reject) => {
            track = localStream.getVideoTracks()[0];

            createConnections((firstConnection) => {
                firstConnection.addTrack(track, localStream);
            }, (secondConnection) => {
                secondConnection.ontrack = (trackEvent) => {
                    resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((remoteStream) => {
        remoteVideo.srcObject = remoteStream;
        return remoteVideo.play();
    });
}, "Setting video exchange");

promise_test(async (test) => {
   await checkVideoBlack(false, remoteVideo, "canvas0");
   await waitForVideoSize(remoteVideo, 320, 240);
}, "Track is enabled, video should not be black");

promise_test(async (test) => {
    await checkVideoBlack(false, localVideo, "canvas0");
    await waitForVideoSize(localVideo, 320, 240);

    if (window.internals)
        window.internals.setCameraMediaStreamTrackOrientation(track, 90);
    if (window.testRunner)
        testRunner.setMockCameraOrientation(90);

    await checkVideoBlack(false, localVideo, "canvas1");
    await waitForVideoSize(localVideo, 240, 320);
}, "Track is enabled and rotated, local video should not be black and should change size");

promise_test(async (test) => {
    if (window.internals)
        window.internals.setCameraMediaStreamTrackOrientation(track, 90);
    if (window.testRunner)
        testRunner.setMockCameraOrientation(90);

    await checkVideoBlack(false, remoteVideo, "canvas2").then(() => {
        return waitForVideoSize(remoteVideo, 240, 320);
    });

    await waitForTrackRotation(remoteVideo.srcObject.getVideoTracks()[0], 90);
}, "Track is enabled and rotated, remote video should not be black and should change size");

promise_test(async (test) => {
    if (window.internals)
        window.internals.setCameraMediaStreamTrackOrientation(track, 180);
    if (window.testRunner)
        testRunner.setMockCameraOrientation(180);

    await checkVideoBlack(false, remoteVideo, "canvas3").then(() => {
        return waitForVideoSize(remoteVideo, 320, 240);
    });

    await waitForTrackRotation(remoteVideo.srcObject.getVideoTracks()[0], 180);
}, "Track is enabled and rotated again, video should not be black and should change size");
        </script>
    </body>
</html>
