tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

RTCRtpEncodingParameters-codec-opus-stereo.https.html (4459B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>RTCRtpEncodingParameters codec opus stereo</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script>
      7 'use strict';
      8 
      9 const kNumChannelsMono = 1;
     10 const kNumChannelsStereo = 2;
     11 const kAudioProcessingEnabled = true;
     12 const kAudioProcessingDisabled = false;
     13 
     14 // In some implementations (e.g. Chrome), whether or not audio processing is
     15 // used may affect the number of channels we get.
     16 // To isolate this factor from the test, we constrain both channels and APM.
     17 function getAudioConstraints(numChannels, audioProcessing) {
     18  return {
     19    channelCount: {exact: numChannels},
     20    autoGainControl: audioProcessing,
     21    echoCancellation: audioProcessing,
     22    noiseSuppression: audioProcessing
     23  };
     24 }
     25 
     26 // Polls getSettings() until `channelCount` is known.
     27 // Remote tracks don't populate their `channelCount` until media is received.
     28 async function pollChannelCount(t, track) {
     29  while (true) {
     30    if (track.getSettings().channelCount != undefined) {
     31      break;
     32    }
     33    await new Promise(r => t.step_timeout(r, 50));
     34  }
     35  return track.getSettings().channelCount;
     36 }
     37 
     38 promise_test(async t => {
     39  const pc1 = new RTCPeerConnection();
     40  t.add_cleanup(() => pc1.close());
     41  const pc2 = new RTCPeerConnection();
     42  t.add_cleanup(() => pc2.close());
     43  pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
     44  pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
     45 
     46  // Open microphone as mono.
     47  const stream = await navigator.mediaDevices.getUserMedia(
     48      {audio: getAudioConstraints(kNumChannelsMono, kAudioProcessingEnabled)});
     49  const [track] = stream.getTracks();
     50  t.add_cleanup(() => track.stop());
     51  // Prerequisite of the test.
     52  assert_equals(track.getSettings().channelCount, 1,
     53                'Can open track in mono');
     54 
     55  // Negotiate opus.
     56  const transceiver = pc1.addTransceiver(track);
     57  transceiver.setCodecPreferences(
     58      RTCRtpSender.getCapabilities('audio').codecs.filter(
     59          codec => codec.mimeType == 'audio/opus'));
     60  await pc1.setLocalDescription();
     61  await pc2.setRemoteDescription(pc1.localDescription);
     62  await pc2.setLocalDescription();
     63  await pc1.setRemoteDescription(pc2.localDescription);
     64 
     65  const [receiver] = pc2.getReceivers();
     66  const remoteTrack = receiver.track;
     67  // Attaching the track to an audio element is needed for media to flow,
     68  // otherwise the `channelCount` is never known.
     69  const audio = document.createElement('audio');
     70  audio.srcObject = new MediaStream();
     71  audio.srcObject.addTrack(remoteTrack);
     72  // The stereo opus decoder outputs stereo regardless of the signal on the
     73  // wire.
     74  assert_equals(await pollChannelCount(t, remoteTrack), 2,
     75                'Remote track is stereo (despite local track being mono)');
     76 }, 'Sending and receiving a mono track with opus (stereo decoder upmix)');
     77 
     78 promise_test(async t => {
     79  const pc1 = new RTCPeerConnection();
     80  t.add_cleanup(() => pc1.close());
     81  const pc2 = new RTCPeerConnection();
     82  t.add_cleanup(() => pc2.close());
     83  pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
     84  pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
     85 
     86  // Open microphone as stereo.
     87  const stream = await navigator.mediaDevices.getUserMedia(
     88    {audio: getAudioConstraints(kNumChannelsStereo, kAudioProcessingDisabled)});
     89  const [track] = stream.getTracks();
     90  t.add_cleanup(() => track.stop());
     91  // Prerequisite of the test.
     92  assert_equals(track.getSettings().channelCount, 2,
     93                'Can open track in stereo');
     94 
     95  // Negotiate opus.
     96  const transceiver = pc1.addTransceiver(track);
     97  transceiver.setCodecPreferences(
     98      RTCRtpSender.getCapabilities('audio').codecs.filter(
     99          codec => codec.mimeType == 'audio/opus'));
    100  await pc1.setLocalDescription();
    101  await pc2.setRemoteDescription(pc1.localDescription);
    102  await pc2.setLocalDescription();
    103  await pc1.setRemoteDescription(pc2.localDescription);
    104 
    105  const [receiver] = pc2.getReceivers();
    106  const remoteTrack = receiver.track;
    107  // Attaching the track to an audio element is needed for media to flow,
    108  // otherwise the `channelCount` is never known.
    109  const audio = document.createElement('audio');
    110  audio.srcObject = new MediaStream();
    111  audio.srcObject.addTrack(remoteTrack);
    112  assert_equals(await pollChannelCount(t, remoteTrack), 2,
    113                'Remote track is also stereo');
    114 }, 'Sending and receiving a stereo track with opus');
    115 </script>