Example #1
0
 private void UpdateCurrentFrame(RTCStats stats)
 {
     switch (stats.StatsType)
     {
     case RTCStatsType.Track:
         RTCMediaStreamTrackStats mediaStreamTrackStats = stats.ToTrack();
         if (mediaStreamTrackStats != null && !mediaStreamTrackStats.TrackId.Contains("audio"))
         {
             if (mediaStreamTrackStats.RemoteSource)
             {
                 FramesPerSecondChanged?.Invoke("PEER", mediaStreamTrackStats.FramesPerSecond.ToString("0.#"));
                 ResolutionChanged?.Invoke("PEER", mediaStreamTrackStats.FrameWidth, mediaStreamTrackStats.FrameHeight);
             }
             else
             {
                 FramesPerSecondChanged?.Invoke("SELF", mediaStreamTrackStats.FramesPerSecond.ToString("0.#"));
                 ResolutionChanged?.Invoke("SELF", mediaStreamTrackStats.FrameWidth, mediaStreamTrackStats.FrameHeight);
             }
         }
         break;
     }
 }
Example #2
0
        private async void CollectCallMetrics3(object state)
        {
            CallDuration += ScheduleTimeInSeconds;
            StatsData statsData = CallsStatsDictionary[_currentId];

            statsData.Timestamps.Add(CallDuration);
            RTCStatsReport report = await StatsProviderPeerConnectionCall.GetStats();

            if (report != null)
            {
                foreach (var statId in report.StatsIds)
                {
                    RTCStats stats = report.GetStats(statId);
                    if (IsStatsCollectionEnabled)
                    {
                        ParseStats(stats, statsData);
                    }
                    else
                    {
                        UpdateCurrentFrame(stats);
                    }
                }
            }
        }
        public static void Test(RTCStats stats)
        {
            switch (stats.Type)
            {
            case RTCStatsType.CandidatePair:
                var iceCandidatePairStats = stats as RTCIceCandidatePairStats;
                Assert.NotNull(iceCandidatePairStats);
                Assert.AreEqual(24, iceCandidatePairStats.Dict.Count);
                Assert.IsNotEmpty(iceCandidatePairStats.transportId);
                Assert.IsNotEmpty(iceCandidatePairStats.localCandidateId);
                Assert.IsNotEmpty(iceCandidatePairStats.remoteCandidateId);
                Assert.IsNotEmpty(iceCandidatePairStats.state);
                Ignore.Pass(iceCandidatePairStats.priority);
                Ignore.Pass(iceCandidatePairStats.nominated);
                Ignore.Pass(iceCandidatePairStats.writable);
                Ignore.Pass(iceCandidatePairStats.readable);
                Ignore.Pass(iceCandidatePairStats.bytesSent);
                Ignore.Pass(iceCandidatePairStats.bytesReceived);
                Ignore.Pass(iceCandidatePairStats.totalRoundTripTime);
                Ignore.Pass(iceCandidatePairStats.currentRoundTripTime);
                Ignore.Pass(iceCandidatePairStats.availableOutgoingBitrate);
                Ignore.Pass(iceCandidatePairStats.availableIncomingBitrate);
                Ignore.Pass(iceCandidatePairStats.consentRequestsReceived);
                Ignore.Pass(iceCandidatePairStats.consentRequestsSent);
                Ignore.Pass(iceCandidatePairStats.requestsReceived);
                Ignore.Pass(iceCandidatePairStats.requestsSent);
                Ignore.Pass(iceCandidatePairStats.responsesReceived);
                Ignore.Pass(iceCandidatePairStats.responsesSent);
                Ignore.Pass(iceCandidatePairStats.retransmissionsReceived);
                Ignore.Pass(iceCandidatePairStats.retransmissionsSent);
                Ignore.Pass(iceCandidatePairStats.consentResponsesReceived);
                Ignore.Pass(iceCandidatePairStats.consentResponsesSent);
                break;

            case RTCStatsType.DataChannel:
                var dataChannelStats = stats as RTCDataChannelStats;
                Assert.NotNull(dataChannelStats);
                Assert.AreEqual(8, dataChannelStats.Dict.Count);
                Assert.IsNotEmpty(dataChannelStats.label);
                Assert.IsNotEmpty(dataChannelStats.state);
                Ignore.Pass(dataChannelStats.protocol);
                Ignore.Pass(dataChannelStats.messagesSent);
                Ignore.Pass(dataChannelStats.messagesReceived);
                Ignore.Pass(dataChannelStats.dataChannelIdentifier);
                Ignore.Pass(dataChannelStats.bytesSent);
                Ignore.Pass(dataChannelStats.bytesReceived);
                break;

            case RTCStatsType.LocalCandidate:
            case RTCStatsType.RemoteCandidate:
                var candidateStats = stats as RTCIceCandidateStats;
                Assert.NotNull(candidateStats);
                Assert.AreEqual(11, candidateStats.Dict.Count);
                Assert.IsNotEmpty(candidateStats.protocol);
                Assert.IsNotEmpty(candidateStats.candidateType);
                Ignore.Pass(candidateStats.ip);
                Assert.IsNotEmpty(candidateStats.transportId);
                Ignore.Pass(candidateStats.url);
                Ignore.Pass(candidateStats.relayProtocol);
                Ignore.Pass(candidateStats.networkType);
                Ignore.Pass(candidateStats.priority);
                Ignore.Pass(candidateStats.deleted);
                Ignore.Pass(candidateStats.isRemote);
                Ignore.Pass(candidateStats.port);
                break;

            case RTCStatsType.Certificate:
                var certificateStats = stats as RTCCertificateStats;
                Assert.NotNull(certificateStats);
                Assert.AreEqual(4, certificateStats.Dict.Count);
                Assert.IsNotEmpty(certificateStats.fingerprint);
                Assert.IsNotEmpty(certificateStats.fingerprintAlgorithm);
                Assert.IsNotEmpty(certificateStats.base64Certificate);
                Ignore.Pass(certificateStats.issuerCertificateId);
                break;

            case RTCStatsType.Codec:
                var codecStats = stats as RTCCodecStats;
                Assert.NotNull(codecStats);
                Assert.AreEqual(6, codecStats.Dict.Count);
                Assert.IsNotEmpty(codecStats.mimeType);
                Assert.IsNotEmpty(codecStats.transportId);
                Ignore.Pass(codecStats.sdpFmtpLine);
                Ignore.Pass(codecStats.payloadType);
                Ignore.Pass(codecStats.clockRate);
                Ignore.Pass(codecStats.channels);
                break;

            case RTCStatsType.InboundRtp:
                var inboundRtpStreamStats = stats as RTCInboundRTPStreamStats;
                Assert.NotNull(inboundRtpStreamStats);
                Assert.AreEqual(56, inboundRtpStreamStats.Dict.Count);
                Ignore.Pass(inboundRtpStreamStats.ssrc);
                Ignore.Pass(inboundRtpStreamStats.isRemote);
                Assert.IsNotEmpty(inboundRtpStreamStats.mediaType);
                Assert.IsNotEmpty(inboundRtpStreamStats.kind);
                Ignore.Pass(inboundRtpStreamStats.trackId);
                Assert.IsNotEmpty(inboundRtpStreamStats.transportId);
                Ignore.Pass(inboundRtpStreamStats.codecId);
                Ignore.Pass(inboundRtpStreamStats.firCount);
                Ignore.Pass(inboundRtpStreamStats.pliCount);
                Ignore.Pass(inboundRtpStreamStats.nackCount);
                Ignore.Pass(inboundRtpStreamStats.sliCount);
                Ignore.Pass(inboundRtpStreamStats.qpSum);
                Ignore.Pass(inboundRtpStreamStats.packetsReceived);
                Ignore.Pass(inboundRtpStreamStats.fecPacketsReceived);
                Ignore.Pass(inboundRtpStreamStats.fecPacketsDiscarded);
                Ignore.Pass(inboundRtpStreamStats.bytesReceived);
                Ignore.Pass(inboundRtpStreamStats.headerBytesReceived);
                Ignore.Pass(inboundRtpStreamStats.packetsLost);
                Ignore.Pass(inboundRtpStreamStats.lastPacketReceivedTimestamp);
                Ignore.Pass(inboundRtpStreamStats.jitter);
                Ignore.Pass(inboundRtpStreamStats.jitterBufferDelay);
                Ignore.Pass(inboundRtpStreamStats.jitterBufferEmittedCount);
                Ignore.Pass(inboundRtpStreamStats.totalSamplesReceived);
                Ignore.Pass(inboundRtpStreamStats.totalSamplesDuration);
                Ignore.Pass(inboundRtpStreamStats.concealedSamples);
                Ignore.Pass(inboundRtpStreamStats.silentConcealedSamples);
                Ignore.Pass(inboundRtpStreamStats.concealmentEvents);
                Ignore.Pass(inboundRtpStreamStats.insertedSamplesForDeceleration);
                Ignore.Pass(inboundRtpStreamStats.removedSamplesForAcceleration);
                Ignore.Pass(inboundRtpStreamStats.audioLevel);
                Ignore.Pass(inboundRtpStreamStats.totalAudioEnergy);
                Ignore.Pass(inboundRtpStreamStats.roundTripTime);
                Ignore.Pass(inboundRtpStreamStats.packetsDiscarded);
                Ignore.Pass(inboundRtpStreamStats.packetsRepaired);
                Ignore.Pass(inboundRtpStreamStats.burstPacketsLost);
                Ignore.Pass(inboundRtpStreamStats.burstPacketsDiscarded);
                Ignore.Pass(inboundRtpStreamStats.burstLossCount);
                Ignore.Pass(inboundRtpStreamStats.burstDiscardCount);
                Ignore.Pass(inboundRtpStreamStats.burstLossRate);
                Ignore.Pass(inboundRtpStreamStats.burstDiscardRate);
                Ignore.Pass(inboundRtpStreamStats.gapLossRate);
                Ignore.Pass(inboundRtpStreamStats.gapDiscardRate);
                Ignore.Pass(inboundRtpStreamStats.framesReceived);
                Ignore.Pass(inboundRtpStreamStats.frameWidth);
                Ignore.Pass(inboundRtpStreamStats.frameHeight);
                Ignore.Pass(inboundRtpStreamStats.frameBitDepth);
                Ignore.Pass(inboundRtpStreamStats.framesPerSecond);
                Ignore.Pass(inboundRtpStreamStats.framesDecoded);
                Ignore.Pass(inboundRtpStreamStats.keyFramesDecoded);
                Ignore.Pass(inboundRtpStreamStats.totalDecodeTime);
                Ignore.Pass(inboundRtpStreamStats.totalInterFrameDelay);
                Ignore.Pass(inboundRtpStreamStats.totalSquaredInterFrameDelay);
                Ignore.Pass(inboundRtpStreamStats.contentType);
                Ignore.Pass(inboundRtpStreamStats.estimatedPlayoutTimestamp);
                Ignore.Pass(inboundRtpStreamStats.decoderImplementation);
                break;

            case RTCStatsType.RemoteInboundRtp:
                var remoteInboundRtpStreamStats = stats as RTCRemoteInboundRtpStreamStats;
                Assert.NotNull(remoteInboundRtpStreamStats);
                Assert.AreEqual(8, remoteInboundRtpStreamStats.Dict.Count);
                Ignore.Pass(remoteInboundRtpStreamStats.ssrc);
                Assert.IsNotEmpty(remoteInboundRtpStreamStats.kind);
                Assert.IsNotEmpty(remoteInboundRtpStreamStats.transportId);
                Assert.IsNotEmpty(remoteInboundRtpStreamStats.codecId);
                Ignore.Pass(remoteInboundRtpStreamStats.packetsLost);
                Ignore.Pass(remoteInboundRtpStreamStats.jitter);
                Assert.IsNotEmpty(remoteInboundRtpStreamStats.localId);
                Ignore.Pass(remoteInboundRtpStreamStats.roundTripTime);
                break;

            case RTCStatsType.Transport:
                var transportStats = stats as RTCTransportStats;
                Assert.NotNull(transportStats);
                Assert.AreEqual(13, transportStats.Dict.Count);
                Ignore.Pass(transportStats.bytesSent);
                Ignore.Pass(transportStats.bytesReceived);
                Ignore.Pass(transportStats.packetsSent);
                Ignore.Pass(transportStats.packetsReceived);
                Ignore.Pass(transportStats.rtcpTransportStatsId);
                Ignore.Pass(transportStats.dtlsState);
                Ignore.Pass(transportStats.selectedCandidatePairId);
                Ignore.Pass(transportStats.localCertificateId);
                Ignore.Pass(transportStats.remoteCertificateId);
                Ignore.Pass(transportStats.tlsVersion);
                Ignore.Pass(transportStats.dtlsCipher);
                Ignore.Pass(transportStats.srtpCipher);
                Ignore.Pass(transportStats.selectedCandidatePairChanges);
                break;

            case RTCStatsType.RemoteOutboundRtp:
            case RTCStatsType.OutboundRtp:
                var outboundRtpStreamStats = stats as RTCOutboundRTPStreamStats;
                Assert.NotNull(outboundRtpStreamStats);
                Assert.AreEqual(35, outboundRtpStreamStats.Dict.Count);
                Ignore.Pass(outboundRtpStreamStats.ssrc);
                Ignore.Pass(outboundRtpStreamStats.isRemote);
                Assert.IsNotEmpty(outboundRtpStreamStats.mediaType);
                Assert.IsNotEmpty(outboundRtpStreamStats.kind);
                Ignore.Pass(outboundRtpStreamStats.trackId);
                Assert.IsNotEmpty(outboundRtpStreamStats.transportId);
                Ignore.Pass(outboundRtpStreamStats.codecId);
                Ignore.Pass(outboundRtpStreamStats.firCount);
                Ignore.Pass(outboundRtpStreamStats.pliCount);
                Ignore.Pass(outboundRtpStreamStats.nackCount);
                Ignore.Pass(outboundRtpStreamStats.sliCount);
                Ignore.Pass(outboundRtpStreamStats.qpSum);
                Ignore.Pass(outboundRtpStreamStats.mediaSourceId);
                Ignore.Pass(outboundRtpStreamStats.remoteId);
                Ignore.Pass(outboundRtpStreamStats.rid);
                Ignore.Pass(outboundRtpStreamStats.packetsSent);
                Ignore.Pass(outboundRtpStreamStats.retransmittedPacketsSent);
                Ignore.Pass(outboundRtpStreamStats.bytesSent);
                Ignore.Pass(outboundRtpStreamStats.headerBytesSent);
                Ignore.Pass(outboundRtpStreamStats.retransmittedBytesSent);
                Ignore.Pass(outboundRtpStreamStats.targetBitrate);
                Ignore.Pass(outboundRtpStreamStats.framesEncoded);
                Ignore.Pass(outboundRtpStreamStats.keyFramesEncoded);
                Ignore.Pass(outboundRtpStreamStats.totalEncodeTime);
                Ignore.Pass(outboundRtpStreamStats.totalEncodedBytesTarget);
                Ignore.Pass(outboundRtpStreamStats.frameWidth);
                Ignore.Pass(outboundRtpStreamStats.frameHeight);
                Ignore.Pass(outboundRtpStreamStats.framesPerSecond);
                Ignore.Pass(outboundRtpStreamStats.framesSent);
                Ignore.Pass(outboundRtpStreamStats.hugeFramesSent);
                Ignore.Pass(outboundRtpStreamStats.totalPacketSendDelay);
                Ignore.Pass(outboundRtpStreamStats.qualityLimitationReason);
                Ignore.Pass(outboundRtpStreamStats.qualityLimitationResolutionChanges);
                Ignore.Pass(outboundRtpStreamStats.contentType);
                Ignore.Pass(outboundRtpStreamStats.encoderImplementation);
                break;

            case RTCStatsType.MediaSource:
                var mediaSourceStats = stats as RTCMediaSourceStats;
                Assert.NotNull(mediaSourceStats);
                Assert.AreEqual(6, mediaSourceStats.Dict.Count);
                Assert.IsNotEmpty(mediaSourceStats.trackIdentifier);
                Assert.IsNotEmpty(mediaSourceStats.kind);
                Ignore.Pass(mediaSourceStats.width);
                Ignore.Pass(mediaSourceStats.height);
                Ignore.Pass(mediaSourceStats.frames);
                Ignore.Pass(mediaSourceStats.framesPerSecond);

                break;

            case RTCStatsType.Track:
                var mediaStreamTrackStats = stats as RTCMediaStreamTrackStats;
                Assert.NotNull(mediaStreamTrackStats);
                Assert.AreEqual(42, mediaStreamTrackStats.Dict.Count);
                Ignore.Pass(mediaStreamTrackStats.trackIdentifier);
                Ignore.Pass(mediaStreamTrackStats.mediaSourceId);
                Ignore.Pass(mediaStreamTrackStats.remoteSource);
                Ignore.Pass(mediaStreamTrackStats.ended);
                Ignore.Pass(mediaStreamTrackStats.detached);
                Ignore.Pass(mediaStreamTrackStats.kind);
                Ignore.Pass(mediaStreamTrackStats.jitterBufferDelay);
                Ignore.Pass(mediaStreamTrackStats.jitterBufferEmittedCount);
                Ignore.Pass(mediaStreamTrackStats.frameWidth);
                Ignore.Pass(mediaStreamTrackStats.frameHeight);
                Ignore.Pass(mediaStreamTrackStats.framesPerSecond);
                Ignore.Pass(mediaStreamTrackStats.framesSent);
                Ignore.Pass(mediaStreamTrackStats.hugeFramesSent);
                Ignore.Pass(mediaStreamTrackStats.framesReceived);
                Ignore.Pass(mediaStreamTrackStats.framesDecoded);
                Ignore.Pass(mediaStreamTrackStats.framesDropped);
                Ignore.Pass(mediaStreamTrackStats.framesCorrupted);
                Ignore.Pass(mediaStreamTrackStats.partialFramesLost);
                Ignore.Pass(mediaStreamTrackStats.fullFramesLost);
                Ignore.Pass(mediaStreamTrackStats.audioLevel);
                Ignore.Pass(mediaStreamTrackStats.totalAudioEnergy);
                Ignore.Pass(mediaStreamTrackStats.echoReturnLoss);
                Ignore.Pass(mediaStreamTrackStats.echoReturnLossEnhancement);
                Ignore.Pass(mediaStreamTrackStats.totalSamplesReceived);
                Ignore.Pass(mediaStreamTrackStats.totalSamplesDuration);
                Ignore.Pass(mediaStreamTrackStats.concealedSamples);
                Ignore.Pass(mediaStreamTrackStats.silentConcealedSamples);
                Ignore.Pass(mediaStreamTrackStats.concealmentEvents);
                Ignore.Pass(mediaStreamTrackStats.insertedSamplesForDeceleration);
                Ignore.Pass(mediaStreamTrackStats.removedSamplesForAcceleration);
                Ignore.Pass(mediaStreamTrackStats.jitterBufferFlushes);
                Ignore.Pass(mediaStreamTrackStats.delayedPacketOutageSamples);
                Ignore.Pass(mediaStreamTrackStats.relativePacketArrivalDelay);
                Ignore.Pass(mediaStreamTrackStats.jitterBufferTargetDelay);
                Ignore.Pass(mediaStreamTrackStats.interruptionCount);
                Ignore.Pass(mediaStreamTrackStats.totalInterruptionDuration);
                Ignore.Pass(mediaStreamTrackStats.freezeCount);
                Ignore.Pass(mediaStreamTrackStats.pauseCount);
                Ignore.Pass(mediaStreamTrackStats.totalFreezesDuration);
                Ignore.Pass(mediaStreamTrackStats.totalPausesDuration);
                Ignore.Pass(mediaStreamTrackStats.totalFramesDuration);
                Ignore.Pass(mediaStreamTrackStats.sumOfSquaredFramesDuration);
                break;

            case RTCStatsType.Stream:
                var mediaStreamStats = stats as RTCMediaStreamStats;
                Assert.NotNull(mediaStreamStats);
                Assert.AreEqual(2, mediaStreamStats.Dict.Count);
                Ignore.Pass(mediaStreamStats.streamIdentifier);
                Ignore.Pass(mediaStreamStats.trackIds);
                break;

            case RTCStatsType.PeerConnection:
                var peerConnectionStats = stats as RTCPeerConnectionStats;
                Assert.NotNull(peerConnectionStats);
                Assert.AreEqual(2, peerConnectionStats.Dict.Count);
                Ignore.Pass(peerConnectionStats.dataChannelsOpened);
                Ignore.Pass(peerConnectionStats.dataChannelsClosed);
                break;

            default:
                Debug.LogWarning(stats.Type);
                break;
            }
        }
Example #4
0
        private void ParseStats(RTCStats stats, StatsData statsData)
        {
            try
            {
                switch (stats.StatsType)
                {
                case RTCStatsType.InboundRtp:
                    //Debug.WriteLine("RTCStatsType.InboundRtp:" + statId);
                    RTCInboundRtpStreamStats inboundRtpStreamStats = stats.ToInboundRtp();
                    if (inboundRtpStreamStats != null)
                    {
                        TrackStatsData tsd =
                            statsData.GetTrackStatsData(inboundRtpStreamStats.RtpStreamStats.MediaTrackId, false);

                        if (tsd != null)
                        {
                            if (statsData.TimeToSetupCall.Milliseconds == 0 && inboundRtpStreamStats.PacketsReceived > 0)
                            {
                                statsData.TimeToSetupCall = DateTime.Now - statsData.StarTime;
                            }

                            //if (!tsd.IsAudio)
                            //    TestReceivedBytes.Add(inboundRtpStreamStats.BytesReceived);
                            tsd.AddAverage(RtcStatsValueName.StatsValueNameBytesReceived,
                                           inboundRtpStreamStats.BytesReceived);

                            //if (!tsd.IsAudio)
                            //TestReceivedPackets.Add(inboundRtpStreamStats.PacketsReceived);
                            tsd.AddAverage(RtcStatsValueName.StatsValueNamePacketsReceived,
                                           inboundRtpStreamStats.PacketsReceived);

                            tsd.AddAverage(RtcStatsValueName.StatsValueNamePacketsLost, inboundRtpStreamStats.PacketsLost);

                            tsd.AddData(RtcStatsValueName.StatsValueNameCurrentEndToEndDelayMs,
                                        inboundRtpStreamStats.EndToEndDelay.TotalMilliseconds);
                        }
                    }
                    break;

                case RTCStatsType.OutboundRtp:
                    RTCOutboundRtpStreamStats outboundRtpStreamStats = stats.ToOutboundRtp();
                    if (outboundRtpStreamStats != null)
                    {
                        TrackStatsData tsd =
                            statsData.GetTrackStatsData(outboundRtpStreamStats.RtpStreamStats.MediaTrackId);

                        if (tsd != null)
                        {
                            tsd.AddAverage(RtcStatsValueName.StatsValueNameBytesSent, outboundRtpStreamStats.BytesSent);

                            tsd.AddAverage(RtcStatsValueName.StatsValueNamePacketsSent, outboundRtpStreamStats.PacketsSent);
                        }
                    }
                    break;

                case RTCStatsType.Track:
                    RTCMediaStreamTrackStats mediaStreamTrackStats = stats.ToTrack();
                    if (mediaStreamTrackStats != null)
                    {
                        try
                        {
                            TrackStatsData tsd =
                                statsData.GetTrackStatsData(mediaStreamTrackStats.TrackId, !mediaStreamTrackStats.RemoteSource);

                            if (tsd != null && !tsd.IsAudio)
                            {
                                if (mediaStreamTrackStats.RemoteSource)
                                {
                                    tsd.AddData(RtcStatsValueName.StatsValueNameFrameRateReceived,
                                                mediaStreamTrackStats.FramesPerSecond);
                                    tsd.AddData(RtcStatsValueName.StatsValueNameFrameWidthReceived,
                                                mediaStreamTrackStats.FrameWidth);
                                    tsd.AddData(RtcStatsValueName.StatsValueNameFrameHeightReceived,
                                                mediaStreamTrackStats.FrameHeight);
                                    FramesPerSecondChanged?.Invoke("PEER", mediaStreamTrackStats.FramesPerSecond.ToString("0.#"));
                                    ResolutionChanged?.Invoke("PEER", mediaStreamTrackStats.FrameWidth, mediaStreamTrackStats.FrameHeight);
                                }
                                else
                                {
                                    tsd.AddData(RtcStatsValueName.StatsValueNameFrameRateSent,
                                                mediaStreamTrackStats.FramesPerSecond);
                                    tsd.AddData(RtcStatsValueName.StatsValueNameFrameWidthSent,
                                                mediaStreamTrackStats.FrameWidth);
                                    tsd.AddData(RtcStatsValueName.StatsValueNameFrameHeightSent,
                                                mediaStreamTrackStats.FrameHeight);
                                    FramesPerSecondChanged?.Invoke("SELF", mediaStreamTrackStats.FramesPerSecond.ToString("0.#"));
                                    ResolutionChanged?.Invoke("SELF", mediaStreamTrackStats.FrameWidth, mediaStreamTrackStats.FrameHeight);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.Write(e);
                        }
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                Debug.Write(e);
            }
        }