You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CodecSelection.spec.js 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import * as JitsiConferenceEvents from '../../JitsiConferenceEvents.ts';
  2. import Listenable from '../util/Listenable.js';
  3. import JingleSessionPC from '../xmpp/JingleSessionPC.js';
  4. import { MockChatRoom, MockStropheConnection } from '../xmpp/MockClasses.js';
  5. import { CodecSelection } from './CodecSelection.js';
  6. import { MockRTC, MockSignalingLayerImpl } from './MockClasses.js';
  7. /**
  8. * MockParticipant
  9. */
  10. class MockParticipant {
  11. /**
  12. * A constructor...
  13. */
  14. constructor(id) {
  15. this.id = id;
  16. }
  17. /**
  18. * Returns the endpoint id of the participant.
  19. * @returns <string>
  20. */
  21. getId() {
  22. return this.id;
  23. }
  24. }
  25. /**
  26. * MockConference
  27. */
  28. class MockConference extends Listenable {
  29. /**
  30. * A constructor...
  31. */
  32. constructor() {
  33. super();
  34. this.options = {
  35. config: {}
  36. };
  37. this.activeMediaSession = undefined;
  38. this.mediaSessions = [];
  39. this.participants = [];
  40. this._signalingLayer = new MockSignalingLayerImpl();
  41. }
  42. /**
  43. * Add a mock participant to the conference
  44. * @param {MockParticipant} participant
  45. * @param {Array<string>} codecList
  46. * @param {String} codecType
  47. */
  48. addParticipant(participant, codecList, codecType) {
  49. this.participants.push(participant);
  50. this._signalingLayer.setPeerMediaInfo(true, participant.getId(), codecList, codecType);
  51. this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED);
  52. }
  53. /**
  54. * Returns the list of participants.
  55. * @returns Array<MockParticipant>
  56. */
  57. getParticipants() {
  58. return this.participants;
  59. }
  60. /**
  61. * Checks if E2EE is enabled.
  62. * @returns {boolean}
  63. */
  64. isE2EEEnabled() {
  65. return false;
  66. }
  67. /**
  68. * Removes the participant from the conference.
  69. * @param {MockParticipant} endpoint
  70. */
  71. removeParticipant(endpoint) {
  72. this.participants = this.participants.filter(p => p !== endpoint);
  73. this._signalingLayer.setPeerMediaInfo(false, endpoint.getId());
  74. this.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT);
  75. }
  76. }
  77. describe('Codec Selection', () => {
  78. /* eslint-disable-next-line no-unused-vars */
  79. let codecSelection;
  80. let conference;
  81. let connection;
  82. let jingleSession;
  83. let options;
  84. let participant1, participant2;
  85. let rtc;
  86. const SID = 'sid12345';
  87. beforeEach(() => {
  88. conference = new MockConference();
  89. connection = new MockStropheConnection();
  90. jingleSession = new JingleSessionPC(
  91. SID,
  92. 'peer1',
  93. 'peer2',
  94. connection,
  95. { },
  96. { },
  97. false,
  98. false);
  99. rtc = new MockRTC();
  100. jingleSession.initialize(
  101. /* ChatRoom */ new MockChatRoom(),
  102. /* RTC */ rtc,
  103. /* Signaling layer */ conference._signalingLayer,
  104. /* options */ { });
  105. conference.jvbJingleSession = jingleSession;
  106. });
  107. describe('when codec preference list is used in config.js', () => {
  108. beforeEach(() => {
  109. options = {
  110. jvb: {
  111. preferenceOrder: [ 'VP9', 'VP8', 'H264' ]
  112. }
  113. };
  114. codecSelection = new CodecSelection(conference, options);
  115. spyOn(jingleSession, 'setVideoCodecs');
  116. });
  117. it('and remote endpoints use the new codec selection logic', () => {
  118. // Add a second user joining the call.
  119. participant1 = new MockParticipant('remote-1');
  120. conference.addParticipant(participant1, [ 'vp9', 'vp8' ]);
  121. expect(jingleSession.setVideoCodecs).toHaveBeenCalledTimes(0);
  122. // Add a third user joining the call with a subset of codecs.
  123. participant2 = new MockParticipant('remote-2');
  124. conference.addParticipant(participant2, [ 'vp8' ]);
  125. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  126. // Make p2 leave the call
  127. conference.removeParticipant(participant2);
  128. expect(jingleSession.setVideoCodecs).toHaveBeenCalledTimes(1);
  129. });
  130. it('and remote endpoints use the old codec selection logic (RN)', () => {
  131. // Add a second user joining the call.
  132. participant1 = new MockParticipant('remote-1');
  133. conference.addParticipant(participant1, null, 'vp8');
  134. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  135. // Add a third user (newer) to the call.
  136. participant2 = new MockParticipant('remote-2');
  137. conference.addParticipant(participant2, [ 'vp9', 'vp8' ]);
  138. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  139. // Make p1 leave the call
  140. conference.removeParticipant(participant1);
  141. expect(jingleSession.setVideoCodecs).toHaveBeenCalledTimes(2);
  142. });
  143. });
  144. describe('when deprecated configs are used in config.js', () => {
  145. beforeEach(() => {
  146. options = {
  147. jvb: {
  148. preferredCodec: 'VP9',
  149. disabledCodec: 'H264'
  150. }
  151. };
  152. codecSelection = new CodecSelection(conference, options);
  153. spyOn(jingleSession, 'setVideoCodecs');
  154. });
  155. it('and remote endpoints use the new codec selection logic', () => {
  156. // Add a second user joining the call.
  157. participant1 = new MockParticipant('remote-1');
  158. conference.addParticipant(participant1, [ 'vp9', 'vp8', 'h264' ]);
  159. expect(jingleSession.setVideoCodecs).toHaveBeenCalledTimes(0);
  160. // Add a third user joining the call with a subset of codecs.
  161. participant2 = new MockParticipant('remote-2');
  162. conference.addParticipant(participant2, [ 'vp8' ]);
  163. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  164. // Make p2 leave the call
  165. conference.removeParticipant(participant2);
  166. expect(jingleSession.setVideoCodecs).toHaveBeenCalledTimes(1);
  167. });
  168. it('and remote endpoint prefers a codec that is locally disabled', () => {
  169. // Add a second user joining the call the prefers H.264 and VP8.
  170. participant1 = new MockParticipant('remote-1');
  171. conference.addParticipant(participant1, [ 'h264', 'vp8' ]);
  172. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  173. });
  174. it('and remote endpoints use the old codec selection logic (RN)', () => {
  175. // Add a second user joining the call.
  176. participant1 = new MockParticipant('remote-1');
  177. conference.addParticipant(participant1, null, 'vp8');
  178. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  179. // Add a third user (newer) to the call.
  180. participant2 = new MockParticipant('remote-2');
  181. conference.addParticipant(participant2, [ 'vp9', 'vp8', 'h264' ]);
  182. expect(jingleSession.setVideoCodecs).toHaveBeenCalledWith([ 'vp8' ]);
  183. // Make p1 leave the call
  184. conference.removeParticipant(participant1);
  185. expect(jingleSession.setVideoCodecs).toHaveBeenCalledTimes(2);
  186. });
  187. });
  188. });