Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!DOCTYPE html>
<meta charset="utf-8">
<title>RTCRtpEncodingParameters codec opus stereo</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
const kNumChannelsMono = 1;
const kNumChannelsStereo = 2;
const kAudioProcessingEnabled = true;
const kAudioProcessingDisabled = false;
// In some implementations (e.g. Chrome), whether or not audio processing is
// used may affect the number of channels we get.
// To isolate this factor from the test, we constrain both channels and APM.
function getAudioConstraints(numChannels, audioProcessing) {
return {
channelCount: {exact: numChannels},
autoGainControl: audioProcessing,
echoCancellation: audioProcessing,
noiseSuppression: audioProcessing
};
}
// Polls getSettings() until `channelCount` is known.
// Remote tracks don't populate their `channelCount` until media is received.
async function pollChannelCount(t, track) {
while (true) {
if (track.getSettings().channelCount != undefined) {
break;
}
await new Promise(r => t.step_timeout(r, 50));
}
return track.getSettings().channelCount;
}
promise_test(async t => {
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
// Open microphone as mono.
const stream = await navigator.mediaDevices.getUserMedia(
{audio: getAudioConstraints(kNumChannelsMono, kAudioProcessingEnabled)});
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
// Prerequisite of the test.
assert_equals(track.getSettings().channelCount, 1,
'Can open track in mono');
// Negotiate opus.
const transceiver = pc1.addTransceiver(track);
transceiver.setCodecPreferences(
RTCRtpSender.getCapabilities('audio').codecs.filter(
codec => codec.mimeType == 'audio/opus'));
await pc1.setLocalDescription();
await pc2.setRemoteDescription(pc1.localDescription);
await pc2.setLocalDescription();
await pc1.setRemoteDescription(pc2.localDescription);
const [receiver] = pc2.getReceivers();
const remoteTrack = receiver.track;
// Attaching the track to an audio element is needed for media to flow,
// otherwise the `channelCount` is never known.
const audio = document.createElement('audio');
audio.srcObject = new MediaStream();
audio.srcObject.addTrack(remoteTrack);
// The stereo opus decoder outputs stereo regardless of the signal on the
// wire.
assert_equals(await pollChannelCount(t, remoteTrack), 2,
'Remote track is stereo (despite local track being mono)');
}, 'Sending and receiving a mono track with opus (stereo decoder upmix)');
promise_test(async t => {
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
// Open microphone as stereo.
const stream = await navigator.mediaDevices.getUserMedia(
{audio: getAudioConstraints(kNumChannelsStereo, kAudioProcessingDisabled)});
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
// Prerequisite of the test.
assert_equals(track.getSettings().channelCount, 2,
'Can open track in stereo');
// Negotiate opus.
const transceiver = pc1.addTransceiver(track);
transceiver.setCodecPreferences(
RTCRtpSender.getCapabilities('audio').codecs.filter(
codec => codec.mimeType == 'audio/opus'));
await pc1.setLocalDescription();
await pc2.setRemoteDescription(pc1.localDescription);
await pc2.setLocalDescription();
await pc1.setRemoteDescription(pc2.localDescription);
const [receiver] = pc2.getReceivers();
const remoteTrack = receiver.track;
// Attaching the track to an audio element is needed for media to flow,
// otherwise the `channelCount` is never known.
const audio = document.createElement('audio');
audio.srcObject = new MediaStream();
audio.srcObject.addTrack(remoteTrack);
assert_equals(await pollChannelCount(t, remoteTrack), 2,
'Remote track is also stereo');
}, 'Sending and receiving a stereo track with opus');
</script>