Add GetMediaStats to StatsReport

Add an API to get basic stats around media.

Relates to #610

mend
This commit is contained in:
obasajujoshua31
2020-09-18 13:50:18 +01:00
committed by Tarrence van As
parent 9d393905c1
commit 7d79c766c9
5 changed files with 62 additions and 2 deletions

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"strconv"
"strings"
"time"
"github.com/pion/rtp"
"github.com/pion/rtp/codecs"
@@ -340,6 +341,7 @@ type RTPCodec struct {
Name string
PayloadType uint8
Payloader rtp.Payloader
statsID string
}
// NewRTPCodec is used to define a new codec
@@ -363,6 +365,7 @@ func NewRTPCodec(
Payloader: payloader,
Type: codecType,
Name: name,
statsID: fmt.Sprintf("RTPCodec-%d", time.Now().UnixNano()),
}
}
@@ -411,3 +414,22 @@ type RTPCapabilities struct {
Codecs []RTPCodecCapability
HeaderExtensions []RTPHeaderExtensionCapability
}
func (m *MediaEngine) collectStats(collector *statsReportCollector) {
for _, codec := range m.codecs {
collector.Collecting()
stats := CodecStats{
Timestamp: statsTimestampFrom(time.Now()),
Type: StatsTypeCodec,
ID: codec.statsID,
PayloadType: codec.PayloadType,
MimeType: codec.MimeType,
ClockRate: codec.ClockRate,
Channels: uint8(codec.Channels),
SDPFmtpLine: codec.SDPFmtpLine,
}
collector.Collect(stats.ID, stats)
}
}

View File

@@ -1958,6 +1958,8 @@ func (pc *PeerConnection) GetStats() StatsReport {
}
pc.mu.Unlock()
pc.api.mediaEngine.collectStats(statsCollector)
return statsCollector.Ready()
}

View File

@@ -153,7 +153,7 @@ type CodecStats struct {
ID string `json:"id"`
// PayloadType as used in RTP encoding or decoding
PayloadType uint32 `json:"payloadType"`
PayloadType uint8 `json:"payloadType"`
// CodecType of this CodecStats
CodecType CodecType `json:"codecType"`
@@ -169,7 +169,7 @@ type CodecStats struct {
ClockRate uint32 `json:"clockRate"`
// Channels is 2 for stereo, missing for most other cases.
Channels uint32 `json:"channels"`
Channels uint8 `json:"channels"`
// SDPFmtpLine is the a=fmtp line in the SDP corresponding to the codec,
// i.e., after the colon following the PT.

View File

@@ -75,4 +75,20 @@ func (r StatsReport) GetCertificateStats(c *Certificate) (CertificateStats, bool
return CertificateStats{}, false
}
return certificateStats, true
}
// GetCodecStats is a helper method to return the associated stats for a given Codec
func (r StatsReport) GetCodecStats(c *RTPCodec) (CodecStats, bool) {
statsID := c.statsID
stats, ok := r[statsID]
if !ok {
return CodecStats{}, false
}
codecStats, ok := stats.(CodecStats)
if !ok {
return CodecStats{}, false
}
return codecStats, true
}

View File

@@ -5,6 +5,8 @@ package webrtc
import (
"encoding/json"
"fmt"
"github.com/stretchr/testify/require"
"math/rand"
"sync"
"testing"
"time"
@@ -98,6 +100,13 @@ func getDataChannelStats(t *testing.T, report StatsReport, dc *DataChannel) Data
return stats
}
func getCodecStats(t *testing.T, report StatsReport, c *RTPCodec) CodecStats {
stats, ok := report.GetCodecStats(c)
assert.True(t, ok)
assert.Equal(t, stats.Type, StatsTypeCodec)
return stats
}
func getTransportStats(t *testing.T, report StatsReport, statsID string) TransportStats {
stats, ok := report[statsID]
assert.True(t, ok)
@@ -194,6 +203,12 @@ func TestPeerConnection_GetStats(t *testing.T) {
offerPC, answerPC, err := newPair()
assert.NoError(t, err)
track1, err := offerPC.NewTrack(DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion1")
require.NoError(t, err)
_, err = offerPC.AddTrack(track1)
require.NoError(t, err)
baseLineReportPCOffer := offerPC.GetStats()
baseLineReportPCAnswer := answerPC.GetStats()
@@ -262,6 +277,11 @@ func TestPeerConnection_GetStats(t *testing.T) {
assert.NotEmpty(t, findLocalCandidateStats(reportPCAnswer))
assert.NotEmpty(t, findRemoteCandidateStats(reportPCAnswer))
assert.NotEmpty(t, findCandidatePairStats(t, reportPCAnswer))
assert.NoError(t, err)
for _, codec := range offerPC.api.mediaEngine.codecs {
codecStat := getCodecStats(t, reportPCOffer, codec)
assert.NotEmpty(t, codecStat)
}
// Close answer DC now
dcWait = sync.WaitGroup{}