115 lines
4.4 KiB
HTML
115 lines
4.4 KiB
HTML
<!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>
|