Skip to content

Commit

Permalink
webrtc wpt: add test for direction-based filtering of codecs
Browse files Browse the repository at this point in the history
to supplement the discussion in
  w3c/webrtc-pc#2937

BUG=324930413

Change-Id: Iebf02aade64030e11590af211fa7bc90f976c592
  • Loading branch information
fippo authored and chromium-wpt-export-bot committed Feb 16, 2024
1 parent e6dbd29 commit 48bff5c
Showing 1 changed file with 128 additions and 0 deletions.
128 changes: 128 additions & 0 deletions webrtc/protocol/codecs-filtered-by-direction.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCPeerConnection Codecs in offer get filtered by direction</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../third_party/sdp/sdp.js"></script>
<script>
'use strict';

function codecEquals(c1, c2) {
return c1.mimeType === c2.mimeType &&
c1.sdpFmtpLine === c2.sdpFmtpLine &&
c1.clockRate === c2.clockRate &&
c1.channels === c2.channels;
}

function h264ProfileMatches(c1, c2) {
if (c1.mimeType !== 'video/H264' || c2.mimeType !== 'video/H264') {
return false;
}
if (!(c1.sdpFmtpLine && c2.sdpFmtpLine)) {
// In practice the sdpFmtpLine should be set for H264.
return false;
}
const parseFmtp = line => {
const parameters = {};
line.split(';')
.map(kv => kv.split('='))
.forEach(([key, value]) => parameters[key] = value);
return parameters
};
const p1 = parseFmtp(c1.sdpFmtpLine);
const p2 = parseFmtp(c2.sdpFmtpLine);
if (p1['packetization-mode'] !== p2['packetization-mode']) {
return false;
}
const levelid1 = p1['profile-level-id'];
const levelid2 = p2['profile-level-id'];
// profile level id should be a hex string with length 6.
if (!(levelid1 && levelid2) || !(levelid1.length == 6 && levelid2.length === 6)) {
return false;
}
if (levelid1 === levelid2) {
return true;
}
// Check profile idc and iop in the first two hex-encoded bytes are the same.
return levelid1.substring(0,4) == levelid2.substring(0, 4);
}

function splitCodecs() {
const sendCodecs = RTCRtpSender.getCapabilities('video').codecs;
const receiveCodecs = RTCRtpReceiver.getCapabilities('video').codecs;
const codecs = {
sendrecv: [],
sendonly: [],
recvonly: [],
};
// Ignore RTX since it is present in capabilities once and has no apt.
for (const receiveCodec of receiveCodecs) {
if (receiveCodec.mimeType === 'video/rtx') continue;
if (sendCodecs.find(sendCodec => codecEquals(sendCodec, receiveCodec)
|| h264ProfileMatches(sendCodec, receiveCodec))) {
codecs.sendrecv.push(receiveCodec);
}
}

for (const sendCodec of sendCodecs) {
if (sendCodec.mimeType === 'video/rtx') continue;
if (!receiveCodecs.find(receiveCodec => codecEquals(sendCodec, receiveCodec))) {
codecs.sendonly.push(sendCodec);
}
}
for (const receiveCodec of receiveCodecs) {
if (receiveCodec.mimeType === 'video/rtx') continue;
if (!sendCodecs.find(sendCodec => codecEquals(sendCodec, receiveCodec))) {
codecs.recvonly.push(receiveCodec);
}
}
return codecs;
}

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());

const allCodecs = splitCodecs();
const transceiver = pc.addTransceiver('video');

transceiver.direction = 'sendrecv';
let offer = await pc.createOffer();
let mediaSection = SDPUtils.getMediaSections(offer.sdp)[0];
let rtpParameters = SDPUtils.parseRtpParameters(mediaSection);
const sendrecvCodecs = rtpParameters.codecs.filter(c => c.name !== 'rtx');
assert_equals(sendrecvCodecs.length, allCodecs.sendrecv.length);
}, 'Codecs get filtered by direction for sendrecv');

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());

const allCodecs = splitCodecs();
const transceiver = pc.addTransceiver('video');

transceiver.direction = 'sendonly'
const offer = await pc.createOffer();
const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0];
const rtpParameters = SDPUtils.parseRtpParameters(mediaSection);
const sendonlyCodecs = rtpParameters.codecs.filter(c => c.name !== 'rtx');
assert_equals(sendonlyCodecs.length, allCodecs.sendrecv.length + allCodecs.sendonly.length);
}, 'Codecs get filtered by direction for sendonly');

promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());

const allCodecs = splitCodecs();
const transceiver = pc.addTransceiver('video');

transceiver.direction = 'recvonly'
const offer = await pc.createOffer();
const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0];
const rtpParameters = SDPUtils.parseRtpParameters(mediaSection);
const recvonlyCodecs = rtpParameters.codecs.filter(c => c.name !== 'rtx');
assert_equals(recvonlyCodecs.length, allCodecs.sendrecv.length + allCodecs.recvonly.length);
}, 'Codecs get filtered by direction for recvonly');

</script>

0 comments on commit 48bff5c

Please sign in to comment.