internal void UpdateReceiver() { var transceiver = Transceiver; Debug.Assert(transceiver != null); bool wantsRecv = (Receiver != null); bool wasReceiving = (_pairedReceiver != null); bool isReceiving = (transceiver.RemoteTrack != null); // Note the extra "isReceiving" check, which ensures that when the remote track was // just removed by OnUnpaired(RemoteTrack) from the TrackRemoved event then it is not // immediately re-added by mistake. var receiverInternal = (_receiver as IMediaReceiverInternal); if (wantsRecv && isReceiving && !wasReceiving) { // Transceiver started receiving, and user actually wants to receive receiverInternal.OnPaired(transceiver.RemoteTrack); _pairedReceiver = receiverInternal; } else if (!isReceiving && wasReceiving) { // Transceiver stopped receiving (user intent does not matter here) receiverInternal.OnUnpaired(transceiver.RemoteTrack); _pairedReceiver = null; } }
internal void OnUnpaired(MediaTrack track) { Debug.Assert(track != null); Debug.Assert(Transceiver != null); Debug.Assert(Transceiver.RemoteTrack == null); // already removed // This is called by the TrackRemoved event, which can be fired sometimes even // though we did not have any opportunity yet to pair. So only unpair if we did. // In details, the case is the answering peer being in sendonly mode, yet created // automatically by the implementation during SetRemoteDescription() in recvonly // mode (per the WebRTC spec). So the SetDirection(sendonly) triggers the TrackRemoved // event, but the pairing was never done because SetDirection() is called before // the received is updated. if (_pairedReceiver != null) { _pairedReceiver.OnUnpaired(track); _pairedReceiver = null; } }