summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webrtc-encoded-transform/script-transform-generateKeyFrame-simulcast.https.html
blob: 4174aaf24a130c0d15508a958fecb82c6ce4582b (plain)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>RTCRtpScriptTransformer.generateKeyFrame simulcast tests</title>
    <meta name='timeout' content='long'>
    <script src='/resources/testharness.js'></script>
    <script src='/resources/testharnessreport.js'></script>
    <script src=/resources/testdriver.js></script>
    <script src=/resources/testdriver-vendor.js></script>
    <script src='../mediacapture-streams/permission-helper.js'></script>
  </head>
  <body>
    <video id='video1' autoplay></video>
    <video id='video2' autoplay></video>
    <script src ='routines.js'></script>
    <script src ='../webrtc/simulcast/simulcast.js'></script>
    <script src ='../webrtc/RTCPeerConnection-helper.js'></script>
    <script src='../webrtc/third_party/sdp/sdp.js'></script>
    <script>

const generateKeyFrame = (port, opts) => postMethod(port, 'generateKeyFrame', opts);
const waitForFrame = port => postMethod(port, 'waitForFrame');

promise_test(async (test) => {
  const worker = await createWorker('script-transform-generateKeyFrame.js');
  const transform = await createTransform(worker);
  const senderPc = new RTCPeerConnection();
  const receiverPc = new RTCPeerConnection();
  // This will only work if first rid is 0
  exchangeIceCandidates(senderPc, receiverPc);
  const stream = await navigator.mediaDevices.getUserMedia({video: true});
  const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]});
  sender.transform = transform;
  await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']);

  let message = await waitForFrame(sender.transform.port);
  assert_equals(message, 'got frame');

  // Spec says ridless generateKeyFrame selects the first stream, so should work
  message = await generateKeyFrame(sender.transform.port);
  assert_equals(message.result, 'success');

  message = await generateKeyFrame(sender.transform.port, {rid: '0'});
  assert_equals(message.result, 'success');

  message = await generateKeyFrame(sender.transform.port, {rid: '1'});
  assert_equals(message.result, 'success');

  message = await generateKeyFrame(sender.transform.port, {rid: '2'});
  assert_equals(message.result, 'success');
}, 'generateKeyFrame works with simulcast rids');

promise_test(async (test) => {
  const worker = await createWorker('script-transform-generateKeyFrame.js');
  const transform = await createTransform(worker);
  const senderPc = new RTCPeerConnection();
  const receiverPc = new RTCPeerConnection();
  // This will only work if first rid is 0
  exchangeIceCandidates(senderPc, receiverPc);
  const stream = await navigator.mediaDevices.getUserMedia({video: true});
  const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]});
  sender.transform = transform;
  await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']);

  let message = await waitForFrame(sender.transform.port);
  assert_equals(message, 'got frame');

  // Remove the '1' encoding
  await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '2']);

  // Spec says ridless generateKeyFrame selects the first stream, so should work
  message = await generateKeyFrame(sender.transform.port);
  assert_equals(message.result, 'success');

  message = await generateKeyFrame(sender.transform.port, {rid: '0'});
  assert_equals(message.result, 'success');

  message = await generateKeyFrame(sender.transform.port, {rid: '1'});
  assert_equals(message.result, 'failure');
  assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);

  message = await generateKeyFrame(sender.transform.port, {rid: '2'});
  assert_equals(message.result, 'success');
}, 'generateKeyFrame for rid that was negotiated away fails');

promise_test(async (test) => {
  const worker = await createWorker('script-transform-generateKeyFrame.js');
  const transform = await createTransform(worker);
  const senderPc = new RTCPeerConnection();
  const receiverPc = new RTCPeerConnection();
  // This will only work if first rid is 0
  exchangeIceCandidates(senderPc, receiverPc);
  const stream = await navigator.mediaDevices.getUserMedia({video: true});
  const {sender} = senderPc.addTransceiver(stream.getTracks()[0], {sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}]});
  sender.transform = transform;
  await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, ['0', '1', '2']);

  let message = await waitForFrame(sender.transform.port);
  assert_equals(message, 'got frame');

  // Drop to unicast
  await doOfferToSendSimulcastAndAnswer(senderPc, receiverPc, []);

  message = await generateKeyFrame(sender.transform.port);
  assert_equals(message.result, 'success');

  // This is really lame, but there could be frames with rids in flight, and
  // there's not really any good way to know when they've been flushed out.
  // If RTCEncodedVideoFrame had a rid field, we might be able to watch for a
  // frame without a rid. We can't just use generateKeyFrame(null) either,
  // because a keyframe in flight with the first rid can resolve it. However,
  // it's reasonable to expect that if we wait for a _second_
  // generateKeyFrame(null), that should not be resolved with a keyframe for
  // '0'
  message = await generateKeyFrame(sender.transform.port);
  assert_equals(message.result, 'success');

  message = await generateKeyFrame(sender.transform.port, {rid: '0'});
  assert_equals(message.result, 'failure');
  assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);

  message = await generateKeyFrame(sender.transform.port, {rid: '1'});
  assert_equals(message.result, 'failure');
  assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);

  message = await generateKeyFrame(sender.transform.port, {rid: '2'});
  assert_equals(message.result, 'failure');
  assert_equals(message.value, 'NotFoundError', `Message: ${message.message}`);
}, 'generateKeyFrame with rid after simulcast->unicast negotiation fails');

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