瀏覽代碼

feat(stats): Logs average number of pixels (resolution).

dev1
George Politis 8 年之前
父節點
當前提交
b42379aca7
共有 1 個文件被更改,包括 168 次插入0 次删除
  1. 168
    0
      modules/statistics/AvgRTPStatsReporter.js

+ 168
- 0
modules/statistics/AvgRTPStatsReporter.js 查看文件

515
         this._avgLocalScreenFPS
515
         this._avgLocalScreenFPS
516
             = new AverageStatReport('stat_avg_framerate_screen_local');
516
             = new AverageStatReport('stat_avg_framerate_screen_local');
517
 
517
 
518
+        /**
519
+         * Average pixels for remote screen streaming videos (reported only if
520
+         * not a <tt>NaN</tt>).
521
+         * @type {AverageStatReport}
522
+         * @private
523
+         */
524
+        this._avgRemoteCameraPixels
525
+            = new AverageStatReport('stat_avg_pixels_remote');
526
+
527
+        /**
528
+         * Average pixels for remote screen streaming videos (reported only if
529
+         * not a <tt>NaN</tt>).
530
+         * @type {AverageStatReport}
531
+         * @private
532
+         */
533
+        this._avgRemoteScreenPixels
534
+            = new AverageStatReport('stat_avg_pixels_screen_remote');
535
+
536
+        /**
537
+         * Average pixels for local video (camera)
538
+         * @type {AverageStatReport}
539
+         * @private
540
+         */
541
+        this._avgLocalCameraPixels
542
+            = new AverageStatReport('stat_avg_pixels_local');
543
+
544
+        /**
545
+         * Average pixels for local screen streaming video (reported only if not
546
+         * a <tt>NaN</tt>).
547
+         * @type {AverageStatReport}
548
+         * @private
549
+         */
550
+        this._avgLocalScreenPixels
551
+            = new AverageStatReport('stat_avg_pixels_screen_local');
552
+
518
         /**
553
         /**
519
          * Average connection quality as defined by
554
          * Average connection quality as defined by
520
          * the {@link ConnectionQuality} module.
555
          * the {@link ConnectionQuality} module.
594
         const bandwidth = data.bandwidth;
629
         const bandwidth = data.bandwidth;
595
         const packetLoss = data.packetLoss;
630
         const packetLoss = data.packetLoss;
596
         const frameRate = data.framerate;
631
         const frameRate = data.framerate;
632
+        const resolution = data.resolution;
597
 
633
 
598
         if (!bitrate) {
634
         if (!bitrate) {
599
             logger.error('No "bitrate"');
635
             logger.error('No "bitrate"');
610
         } else if (!frameRate) {
646
         } else if (!frameRate) {
611
             logger.error('No "framerate"');
647
             logger.error('No "framerate"');
612
 
648
 
649
+            return;
650
+        } else if (!resolution) {
651
+            logger.error('No resolution');
652
+
613
             return;
653
             return;
614
         }
654
         }
615
 
655
 
646
                     frameRate, true /* local */, VideoType.DESKTOP));
686
                     frameRate, true /* local */, VideoType.DESKTOP));
647
         }
687
         }
648
 
688
 
689
+        if (resolution) {
690
+            this._avgRemoteCameraPixels.addNext(
691
+                this._calculateAvgVideoPixels(
692
+                    resolution, false /* remote */, VideoType.CAMERA));
693
+
694
+            this._avgRemoteScreenPixels.addNext(
695
+                this._calculateAvgVideoPixels(
696
+                    resolution, false /* remote */, VideoType.DESKTOP));
697
+
698
+            this._avgLocalCameraPixels.addNext(
699
+                this._calculateAvgVideoPixels(
700
+                    resolution, true /* local */, VideoType.CAMERA));
701
+
702
+            this._avgLocalScreenPixels.addNext(
703
+                this._calculateAvgVideoPixels(
704
+                    resolution, true /* local */, VideoType.DESKTOP));
705
+        }
706
+
649
         this._sampleIdx += 1;
707
         this._sampleIdx += 1;
650
 
708
 
651
         if (this._sampleIdx >= this._n) {
709
         if (this._sampleIdx >= this._n) {
686
                 this._avgLocalScreenFPS.appendReport(batchReport);
744
                 this._avgLocalScreenFPS.appendReport(batchReport);
687
             }
745
             }
688
 
746
 
747
+            this._avgRemoteCameraPixels.appendReport(batchReport);
748
+            if (!isNaN(this._avgRemoteScreenPixels.calculate())) {
749
+                this._avgRemoteScreenPixels.appendReport(batchReport);
750
+            }
751
+            this._avgLocalCameraPixels.appendReport(batchReport);
752
+            if (!isNaN(this._avgLocalScreenPixels.calculate())) {
753
+                this._avgLocalScreenPixels.appendReport(batchReport);
754
+            }
755
+
689
             this._avgCQ.appendReport(batchReport);
756
             this._avgCQ.appendReport(batchReport);
690
 
757
 
691
             Statistics.analytics.sendEvent(AVG_RTP_STATS_EVENT, batchReport);
758
             Statistics.analytics.sendEvent(AVG_RTP_STATS_EVENT, batchReport);
694
         }
761
         }
695
     }
762
     }
696
 
763
 
764
+    /**
765
+     * Calculates average number of pixels for the report
766
+     *
767
+     * @param {map} peerResolutions a map of peer resolutions
768
+     * @param {boolean} isLocal if the average is to be calculated for the local
769
+     * video or <tt>false</tt> if for remote videos.
770
+     * @param {VideoType} videoType
771
+     * @return {number|NaN} average number of pixels or <tt>NaN</tt> if there
772
+     * are no samples.
773
+     * @private
774
+     */
775
+    _calculateAvgVideoPixels(peerResolutions, isLocal, videoType) {
776
+        let peerPixelsSum = 0;
777
+        let peerCount = 0;
778
+        const myID = this._conference.myUserId();
779
+
780
+        for (const peerID of Object.keys(peerResolutions)) {
781
+            if (isLocal ? peerID === myID : peerID !== myID) {
782
+                const participant
783
+                    = isLocal
784
+                    ? null : this._conference.getParticipantById(peerID);
785
+                const videosResolution = peerResolutions[peerID];
786
+
787
+                // Do not continue without participant for non local peerID
788
+                if ((isLocal || participant) && videosResolution) {
789
+                    const peerAvgPixels = this._calculatePeerAvgVideoPixels(
790
+                        videosResolution, participant, videoType);
791
+
792
+                    if (!isNaN(peerAvgPixels)) {
793
+                        peerPixelsSum += peerAvgPixels;
794
+                        peerCount += 1;
795
+                    }
796
+                }
797
+            }
798
+        }
799
+
800
+        return peerPixelsSum / peerCount;
801
+    }
802
+
803
+    /**
804
+     * Calculate average pixels for either remote or local participant
805
+     * @param {object} videos maps resolution per video SSRC
806
+     * @param {JitsiParticipant|null} participant remote participant or
807
+     * <tt>null</tt> for local video pixels calculation.
808
+     * @param {VideoType} videoType the type of the video for which an average
809
+     * will be calculated.
810
+     * @return {number|NaN} average video pixels of all participant's videos or
811
+     * <tt>NaN</tt> if currently not available
812
+     * @private
813
+     */
814
+    _calculatePeerAvgVideoPixels(videos, participant, videoType) {
815
+        let ssrcs = Object.keys(videos).map(ssrc => Number(ssrc));
816
+        let videoTracks = null;
817
+
818
+        // NOTE that this method is supposed to be called for the stats
819
+        // received from the current peerconnection.
820
+        const tpc = this._conference.getActivePeerConnection();
821
+
822
+        if (participant) {
823
+            videoTracks = participant.getTracksByMediaType(MediaType.VIDEO);
824
+            if (videoTracks) {
825
+                ssrcs
826
+                    = ssrcs.filter(
827
+                    ssrc => videoTracks.find(
828
+                        track => !track.isMuted()
829
+                            && track.getSSRC() === ssrc
830
+                            && track.videoType === videoType));
831
+            }
832
+        } else {
833
+            videoTracks = this._conference.getLocalTracks(MediaType.VIDEO);
834
+            ssrcs
835
+                = ssrcs.filter(
836
+                ssrc => videoTracks.find(
837
+                    track => !track.isMuted()
838
+                        && tpc.getLocalSSRC(track) === ssrc
839
+                        && track.videoType === videoType));
840
+        }
841
+
842
+        let peerPixelsSum = 0;
843
+        let peerSsrcCount = 0;
844
+
845
+        for (const ssrc of ssrcs) {
846
+            const peerSsrcPixels
847
+                = Number(videos[ssrc].height) * Number(videos[ssrc].width);
848
+
849
+            // FPS is reported as 0 for users with no video
850
+            if (!isNaN(peerSsrcPixels) && peerSsrcPixels > 0) {
851
+                peerPixelsSum += peerSsrcPixels;
852
+                peerSsrcCount += 1;
853
+            }
854
+        }
855
+
856
+        return peerPixelsSum / peerSsrcCount;
857
+    }
858
+
859
+
697
     /**
860
     /**
698
      * Calculates average FPS for the report
861
      * Calculates average FPS for the report
699
      * @param {go figure} frameRate
862
      * @param {go figure} frameRate
822
         this._avgLocalFPS.reset();
985
         this._avgLocalFPS.reset();
823
         this._avgLocalScreenFPS.reset();
986
         this._avgLocalScreenFPS.reset();
824
 
987
 
988
+        this._avgRemoteCameraPixels.reset();
989
+        this._avgRemoteScreenPixels.reset();
990
+        this._avgLocalCameraPixels.reset();
991
+        this._avgLocalScreenPixels.reset();
992
+
825
         this._avgCQ.reset();
993
         this._avgCQ.reset();
826
 
994
 
827
         this._sampleIdx = 0;
995
         this._sampleIdx = 0;

Loading…
取消
儲存