Skip to content

Commit

Permalink
fix: disallow requests for none layer (#3260)
Browse files Browse the repository at this point in the history
  • Loading branch information
KaustubhKumar05 authored Sep 13, 2024
1 parent 50cc43e commit ab8423a
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ export default class HMSSubscribeConnection extends HMSConnection {
});

const remote = this.remoteStreams.get(streamId)!;
const TrackCls = e.track.kind === 'audio' ? HMSRemoteAudioTrack : HMSRemoteVideoTrack;
const track = new TrackCls(remote, e.track);
const isAudioTrack = e.track.kind === 'audio';
const TrackCls = isAudioTrack ? HMSRemoteAudioTrack : HMSRemoteVideoTrack;
const track = isAudioTrack
? new TrackCls(remote, e.track)
: new TrackCls(remote, e.track, undefined, this.isFlagEnabled(InitFlags.FLAG_DISABLE_NONE_LAYER_REQUEST));
// reset the simulcast layer to none when new video tracks are added, UI will subscribe when required
if (e.track.kind === 'video') {
remote.setVideoLayerLocally(HMSSimulcastLayer.NONE, 'addTrack', 'subscribeConnection');
Expand Down
1 change: 1 addition & 0 deletions packages/hms-video-store/src/interfaces/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface HMSRoom {
max_size?: number;
large_room_optimization?: boolean;
isEffectsEnabled?: boolean;
disableNoneLayerRequest?: boolean;
isVBEnabled?: boolean;
effectsKey?: string;
isHipaaEnabled?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ export class HMSRemoteVideoTrack extends HMSVideoTrack {
private history = new TrackHistory();
private preferredLayer: HMSPreferredSimulcastLayer = HMSSimulcastLayer.HIGH;
private bizTrackId!: string;
private disableNoneLayerRequest = false;

constructor(stream: HMSRemoteStream, track: MediaStreamTrack, source?: string) {
constructor(stream: HMSRemoteStream, track: MediaStreamTrack, source?: string, disableNoneLayerRequest?: boolean) {
super(stream, track, source);
this.disableNoneLayerRequest = !!disableNoneLayerRequest;
this.setVideoHandler(new VideoElementManager(this));
}

Expand Down Expand Up @@ -170,7 +172,10 @@ export class HMSRemoteVideoTrack extends HMSVideoTrack {
}

private async updateLayer(source: string) {
const newLayer = this.degraded || !this.enabled || !this.hasSinks() ? HMSSimulcastLayer.NONE : this.preferredLayer;
const newLayer =
(this.degraded || !this.enabled || !this.hasSinks()) && !this.disableNoneLayerRequest
? HMSSimulcastLayer.NONE
: this.preferredLayer;
if (!this.shouldSendVideoLayer(newLayer, source)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('remoteVideoTrack', () => {
const connection = { sendOverApiDataChannelWithResponse } as unknown as HMSSubscribeConnection;
stream = new HMSRemoteStream(nativeStream, connection);
nativeTrack = { id: trackId, kind: 'video', enabled: true } as MediaStreamTrack;
track = new HMSRemoteVideoTrack(stream, nativeTrack, 'regular');
track = new HMSRemoteVideoTrack(stream, nativeTrack, 'regular', false);
window.MediaStream = jest.fn().mockImplementation(() => ({
addTrack: jest.fn(),
// Add any method you want to mock
Expand Down Expand Up @@ -156,3 +156,63 @@ describe('remoteVideoTrack', () => {
expectLayersSent([HMSSimulcastLayer.HIGH, HMSSimulcastLayer.NONE]);
});
});

describe('HMSRemoteVideoTrack with disableNoneLayerRequest', () => {
let stream: HMSRemoteStream;
let sendOverApiDataChannelWithResponse: jest.Mock;
let track: HMSRemoteVideoTrack;
let nativeTrack: MediaStreamTrack;
let videoElement: HTMLVideoElement;
const trackId = 'test-track-id';

beforeEach(() => {
videoElement = document.createElement('video');
sendOverApiDataChannelWithResponse = jest.fn();
const connection = { sendOverApiDataChannelWithResponse } as unknown as HMSSubscribeConnection;
const nativeStream = new MediaStream();
stream = new HMSRemoteStream(nativeStream, connection);
nativeTrack = { id: trackId, kind: 'video', enabled: true } as MediaStreamTrack;
track = new HMSRemoteVideoTrack(stream, nativeTrack, 'regular', true); // disableNoneLayerRequest flag is set
track.setTrackId(trackId);

window.MediaStream = jest.fn().mockImplementation(() => ({
addTrack: jest.fn(),
}));
});

const expectLayersSent = (layers: HMSSimulcastLayer[]) => {
const allCalls = sendOverApiDataChannelWithResponse.mock.calls;
expect(allCalls.length).toBe(layers.length);
for (let i = 0; i < allCalls.length; i++) {
const data = allCalls[i][0];
expect(data.params.max_spatial_layer).toBe(layers[i]);
}
};

const sfuDegrades = () => {
track.setLayerFromServer({
subscriber_degraded: true,
expected_layer: HMSSimulcastLayer.HIGH,
current_layer: HMSSimulcastLayer.NONE,
publisher_degraded: false,
track_id: trackId,
});
};

test('disableNoneLayerRequest - degradation', async () => {
await track.addSink(videoElement);
expectLayersSent([HMSSimulcastLayer.HIGH]);

sfuDegrades();
expectLayersSent([HMSSimulcastLayer.HIGH]);
});

test('disableNoneLayerRequest - mute and removeSink', async () => {
await track.addSink(videoElement);
track.setEnabled(false);
expectLayersSent([HMSSimulcastLayer.HIGH]);

await track.removeSink(videoElement);
expectLayersSent([HMSSimulcastLayer.HIGH]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ export class OnDemandTrackManager extends TrackManager {
const remoteStream = new HMSRemoteStream(new MediaStream(), this.transport.getSubscribeConnection()!);
const emptyTrack = LocalTrackManager.getEmptyVideoTrack();
emptyTrack.enabled = !trackInfo.mute;
const track = new HMSRemoteVideoTrack(remoteStream, emptyTrack, trackInfo.source);
const track = new HMSRemoteVideoTrack(
remoteStream,
emptyTrack,
trackInfo.source,
this.store.getRoom()?.disableNoneLayerRequest,
);
track.setTrackId(trackInfo.track_id);
track.peerId = hmsPeer.peerId;
track.logIdentifier = hmsPeer.name;
Expand Down
1 change: 1 addition & 0 deletions packages/hms-video-store/src/reactive-store/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export class SDKToHMS {
peerCount: sdkRoom.peerCount,
isLargeRoom: sdkRoom.large_room_optimization,
isEffectsEnabled: sdkRoom.isEffectsEnabled,
disableNoneLayerRequest: sdkRoom.disableNoneLayerRequest,
isVBEnabled: sdkRoom.isVBEnabled,
effectsKey: sdkRoom.effectsKey,
isHipaaEnabled: sdkRoom.isHipaaEnabled,
Expand Down
1 change: 1 addition & 0 deletions packages/hms-video-store/src/schema/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface HMSRoom {
peerCount?: number;
isLargeRoom?: boolean;
isEffectsEnabled?: boolean;
disableNoneLayerRequest?: boolean;
isVBEnabled?: boolean;
effectsKey?: string;
isHipaaEnabled?: boolean;
Expand Down
1 change: 1 addition & 0 deletions packages/hms-video-store/src/sdk/models/HMSRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default class Room implements HMSRoom {
large_room_optimization?: boolean;
transcriptions?: HMSTranscriptionInfo[] = [];
isEffectsEnabled?: boolean;
disableNoneLayerRequest?: boolean;
isVBEnabled?: boolean;
effectsKey?: string;
isHipaaEnabled?: boolean;
Expand Down
1 change: 1 addition & 0 deletions packages/hms-video-store/src/signal/init/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ export enum InitFlags {
FLAG_HIPAA_ENABLED = 'hipaa',
FLAG_NOISE_CANCELLATION = 'noiseCancellation',
FLAG_SCALE_SCREENSHARE_BASED_ON_PIXELS = 'scaleScreenshareBasedOnPixels',
FLAG_DISABLE_NONE_LAYER_REQUEST = 'disableNoneLayerRequest',
}
1 change: 1 addition & 0 deletions packages/hms-video-store/src/transport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,7 @@ export default class HMSTransport {
if (room) {
room.effectsKey = this.initConfig.config.vb?.effectsKey;
room.isEffectsEnabled = this.isFlagEnabled(InitFlags.FLAG_EFFECTS_SDK_ENABLED);
room.disableNoneLayerRequest = this.isFlagEnabled(InitFlags.FLAG_DISABLE_NONE_LAYER_REQUEST);
room.isVBEnabled = this.isFlagEnabled(InitFlags.FLAG_VB_ENABLED);
room.isHipaaEnabled = this.isFlagEnabled(InitFlags.FLAG_HIPAA_ENABLED);
room.isNoiseCancellationEnabled = this.isFlagEnabled(InitFlags.FLAG_NOISE_CANCELLATION);
Expand Down

0 comments on commit ab8423a

Please sign in to comment.