mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
For regression test, add srs-bench to 3rdparty
This commit is contained in:
parent
de87dd427d
commit
876210f6c9
1158 changed files with 256967 additions and 3 deletions
5
trunk/3rdparty/srs-bench/rtc/pion_constants.go
vendored
Normal file
5
trunk/3rdparty/srs-bench/rtc/pion_constants.go
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
package rtc
|
||||
|
||||
const (
|
||||
rtpOutboundMTU = 1200
|
||||
)
|
27
trunk/3rdparty/srs-bench/rtc/pion_mediaengine.go
vendored
Normal file
27
trunk/3rdparty/srs-bench/rtc/pion_mediaengine.go
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
package rtc
|
||||
|
||||
import (
|
||||
"github.com/pion/rtp"
|
||||
"github.com/pion/rtp/codecs"
|
||||
"github.com/pion/webrtc/v3"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func payloaderForCodec(codec webrtc.RTPCodecCapability) (rtp.Payloader, error) {
|
||||
switch strings.ToLower(codec.MimeType) {
|
||||
case strings.ToLower(webrtc.MimeTypeH264):
|
||||
return &codecs.H264Payloader{}, nil
|
||||
case strings.ToLower(webrtc.MimeTypeOpus):
|
||||
return &codecs.OpusPayloader{}, nil
|
||||
case strings.ToLower(webrtc.MimeTypeVP8):
|
||||
return &codecs.VP8Payloader{}, nil
|
||||
case strings.ToLower(webrtc.MimeTypeVP9):
|
||||
return &codecs.VP9Payloader{}, nil
|
||||
case strings.ToLower(webrtc.MimeTypeG722):
|
||||
return &codecs.G722Payloader{}, nil
|
||||
case strings.ToLower(webrtc.MimeTypePCMU), strings.ToLower(webrtc.MimeTypePCMA):
|
||||
return &codecs.G711Payloader{}, nil
|
||||
default:
|
||||
return nil, webrtc.ErrNoPayloaderForCodec
|
||||
}
|
||||
}
|
27
trunk/3rdparty/srs-bench/rtc/pion_rtpcodec.go
vendored
Normal file
27
trunk/3rdparty/srs-bench/rtc/pion_rtpcodec.go
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
package rtc
|
||||
|
||||
import (
|
||||
"github.com/pion/webrtc/v3"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Do a fuzzy find for a codec in the list of codecs
|
||||
// Used for lookup up a codec in an existing list to find a match
|
||||
func codecParametersFuzzySearch(needle webrtc.RTPCodecParameters, haystack []webrtc.RTPCodecParameters) (webrtc.RTPCodecParameters, error) {
|
||||
// First attempt to match on MimeType + SDPFmtpLine
|
||||
for _, c := range haystack {
|
||||
if strings.EqualFold(c.RTPCodecCapability.MimeType, needle.RTPCodecCapability.MimeType) &&
|
||||
c.RTPCodecCapability.SDPFmtpLine == needle.RTPCodecCapability.SDPFmtpLine {
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to just MimeType
|
||||
for _, c := range haystack {
|
||||
if strings.EqualFold(c.RTPCodecCapability.MimeType, needle.RTPCodecCapability.MimeType) {
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
return webrtc.RTPCodecParameters{}, webrtc.ErrCodecNotFound
|
||||
}
|
246
trunk/3rdparty/srs-bench/rtc/pion_track_local_static.go
vendored
Normal file
246
trunk/3rdparty/srs-bench/rtc/pion_track_local_static.go
vendored
Normal file
|
@ -0,0 +1,246 @@
|
|||
package rtc
|
||||
|
||||
import (
|
||||
"github.com/pion/rtp"
|
||||
"github.com/pion/webrtc/v3"
|
||||
"github.com/pion/webrtc/v3/pkg/media"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// trackBinding is a single bind for a Track
|
||||
// Bind can be called multiple times, this stores the
|
||||
// result for a single bind call so that it can be used when writing
|
||||
type trackBinding struct {
|
||||
id string
|
||||
ssrc webrtc.SSRC
|
||||
payloadType webrtc.PayloadType
|
||||
writeStream webrtc.TrackLocalWriter
|
||||
}
|
||||
|
||||
// TrackLocalStaticRTP is a TrackLocal that has a pre-set codec and accepts RTP Packets.
|
||||
// If you wish to send a media.Sample use TrackLocalStaticSample
|
||||
type TrackLocalStaticRTP struct {
|
||||
mu sync.RWMutex
|
||||
bindings []trackBinding
|
||||
codec webrtc.RTPCodecCapability
|
||||
id, streamID string
|
||||
}
|
||||
|
||||
// NewTrackLocalStaticRTP returns a TrackLocalStaticRTP.
|
||||
func NewTrackLocalStaticRTP(c webrtc.RTPCodecCapability, id, streamID string) (*TrackLocalStaticRTP, error) {
|
||||
return &TrackLocalStaticRTP{
|
||||
codec: c,
|
||||
bindings: []trackBinding{},
|
||||
id: id,
|
||||
streamID: streamID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Bind is called by the PeerConnection after negotiation is complete
|
||||
// This asserts that the code requested is supported by the remote peer.
|
||||
// If so it setups all the state (SSRC and PayloadType) to have a call
|
||||
func (s *TrackLocalStaticRTP) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
parameters := webrtc.RTPCodecParameters{RTPCodecCapability: s.codec}
|
||||
if codec, err := codecParametersFuzzySearch(parameters, t.CodecParameters()); err == nil {
|
||||
s.bindings = append(s.bindings, trackBinding{
|
||||
ssrc: t.SSRC(),
|
||||
payloadType: codec.PayloadType,
|
||||
writeStream: t.WriteStream(),
|
||||
id: t.ID(),
|
||||
})
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
return webrtc.RTPCodecParameters{}, webrtc.ErrUnsupportedCodec
|
||||
}
|
||||
|
||||
// Unbind implements the teardown logic when the track is no longer needed. This happens
|
||||
// because a track has been stopped.
|
||||
func (s *TrackLocalStaticRTP) Unbind(t webrtc.TrackLocalContext) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
for i := range s.bindings {
|
||||
if s.bindings[i].id == t.ID() {
|
||||
s.bindings[i] = s.bindings[len(s.bindings)-1]
|
||||
s.bindings = s.bindings[:len(s.bindings)-1]
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return webrtc.ErrUnbindFailed
|
||||
}
|
||||
|
||||
// ID is the unique identifier for this Track. This should be unique for the
|
||||
// stream, but doesn't have to globally unique. A common example would be 'audio' or 'video'
|
||||
// and StreamID would be 'desktop' or 'webcam'
|
||||
func (s *TrackLocalStaticRTP) ID() string { return s.id }
|
||||
|
||||
// StreamID is the group this track belongs too. This must be unique
|
||||
func (s *TrackLocalStaticRTP) StreamID() string { return s.streamID }
|
||||
|
||||
// Kind controls if this TrackLocal is audio or video
|
||||
func (s *TrackLocalStaticRTP) Kind() webrtc.RTPCodecType {
|
||||
switch {
|
||||
case strings.HasPrefix(s.codec.MimeType, "audio/"):
|
||||
return webrtc.RTPCodecTypeAudio
|
||||
case strings.HasPrefix(s.codec.MimeType, "video/"):
|
||||
return webrtc.RTPCodecTypeVideo
|
||||
default:
|
||||
return webrtc.RTPCodecType(0)
|
||||
}
|
||||
}
|
||||
|
||||
// Codec gets the Codec of the track
|
||||
func (s *TrackLocalStaticRTP) Codec() webrtc.RTPCodecCapability {
|
||||
return s.codec
|
||||
}
|
||||
|
||||
// WriteRTP writes a RTP Packet to the TrackLocalStaticRTP
|
||||
// If one PeerConnection fails the packets will still be sent to
|
||||
// all PeerConnections. The error message will contain the ID of the failed
|
||||
// PeerConnections so you can remove them
|
||||
func (s *TrackLocalStaticRTP) WriteRTP(p *rtp.Packet) error {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
writeErrs := []error{}
|
||||
outboundPacket := *p
|
||||
|
||||
for _, b := range s.bindings {
|
||||
outboundPacket.Header.SSRC = uint32(b.ssrc)
|
||||
outboundPacket.Header.PayloadType = uint8(b.payloadType)
|
||||
if _, err := b.writeStream.WriteRTP(&outboundPacket.Header, outboundPacket.Payload); err != nil {
|
||||
writeErrs = append(writeErrs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return FlattenErrs(writeErrs)
|
||||
}
|
||||
|
||||
// Write writes a RTP Packet as a buffer to the TrackLocalStaticRTP
|
||||
// If one PeerConnection fails the packets will still be sent to
|
||||
// all PeerConnections. The error message will contain the ID of the failed
|
||||
// PeerConnections so you can remove them
|
||||
func (s *TrackLocalStaticRTP) Write(b []byte) (n int, err error) {
|
||||
packet := &rtp.Packet{}
|
||||
if err = packet.Unmarshal(b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return len(b), s.WriteRTP(packet)
|
||||
}
|
||||
|
||||
// TrackLocalStaticSample is a TrackLocal that has a pre-set codec and accepts Samples.
|
||||
// If you wish to send a RTP Packet use TrackLocalStaticRTP
|
||||
type TrackLocalStaticSample struct {
|
||||
packetizer rtp.Packetizer
|
||||
rtpTrack *TrackLocalStaticRTP
|
||||
clockRate float64
|
||||
|
||||
// Set the callback before write RTP packet.
|
||||
OnBeforeWritePacket func(rtp *rtp.Packet)
|
||||
}
|
||||
|
||||
// NewTrackLocalStaticSample returns a TrackLocalStaticSample
|
||||
func NewTrackLocalStaticSample(c webrtc.RTPCodecCapability, id, streamID string) (*TrackLocalStaticSample, error) {
|
||||
rtpTrack, err := NewTrackLocalStaticRTP(c, id, streamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TrackLocalStaticSample{
|
||||
rtpTrack: rtpTrack,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ID is the unique identifier for this Track. This should be unique for the
|
||||
// stream, but doesn't have to globally unique. A common example would be 'audio' or 'video'
|
||||
// and StreamID would be 'desktop' or 'webcam'
|
||||
func (s *TrackLocalStaticSample) ID() string { return s.rtpTrack.ID() }
|
||||
|
||||
// StreamID is the group this track belongs too. This must be unique
|
||||
func (s *TrackLocalStaticSample) StreamID() string { return s.rtpTrack.StreamID() }
|
||||
|
||||
// Kind controls if this TrackLocal is audio or video
|
||||
func (s *TrackLocalStaticSample) Kind() webrtc.RTPCodecType { return s.rtpTrack.Kind() }
|
||||
|
||||
// Codec gets the Codec of the track
|
||||
func (s *TrackLocalStaticSample) Codec() webrtc.RTPCodecCapability {
|
||||
return s.rtpTrack.Codec()
|
||||
}
|
||||
|
||||
// Bind is called by the PeerConnection after negotiation is complete
|
||||
// This asserts that the code requested is supported by the remote peer.
|
||||
// If so it setups all the state (SSRC and PayloadType) to have a call
|
||||
func (s *TrackLocalStaticSample) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters, error) {
|
||||
codec, err := s.rtpTrack.Bind(t)
|
||||
if err != nil {
|
||||
return codec, err
|
||||
}
|
||||
|
||||
s.rtpTrack.mu.Lock()
|
||||
defer s.rtpTrack.mu.Unlock()
|
||||
|
||||
// We only need one packetizer
|
||||
if s.packetizer != nil {
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
payloader, err := payloaderForCodec(codec.RTPCodecCapability)
|
||||
if err != nil {
|
||||
return codec, err
|
||||
}
|
||||
|
||||
s.packetizer = rtp.NewPacketizer(
|
||||
rtpOutboundMTU,
|
||||
0, // Value is handled when writing
|
||||
0, // Value is handled when writing
|
||||
payloader,
|
||||
rtp.NewRandomSequencer(),
|
||||
codec.ClockRate,
|
||||
)
|
||||
s.clockRate = float64(codec.RTPCodecCapability.ClockRate)
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
// Unbind implements the teardown logic when the track is no longer needed. This happens
|
||||
// because a track has been stopped.
|
||||
func (s *TrackLocalStaticSample) Unbind(t webrtc.TrackLocalContext) error {
|
||||
return s.rtpTrack.Unbind(t)
|
||||
}
|
||||
|
||||
// WriteSample writes a Sample to the TrackLocalStaticSample
|
||||
// If one PeerConnection fails the packets will still be sent to
|
||||
// all PeerConnections. The error message will contain the ID of the failed
|
||||
// PeerConnections so you can remove them
|
||||
func (s *TrackLocalStaticSample) WriteSample(sample media.Sample) error {
|
||||
s.rtpTrack.mu.RLock()
|
||||
p := s.packetizer
|
||||
clockRate := s.clockRate
|
||||
s.rtpTrack.mu.RUnlock()
|
||||
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
samples := sample.Duration.Seconds() * clockRate
|
||||
packets := p.(rtp.Packetizer).Packetize(sample.Data, uint32(samples))
|
||||
|
||||
writeErrs := []error{}
|
||||
for _, p := range packets {
|
||||
if s.OnBeforeWritePacket != nil {
|
||||
s.OnBeforeWritePacket(p)
|
||||
}
|
||||
|
||||
if err := s.rtpTrack.WriteRTP(p); err != nil {
|
||||
writeErrs = append(writeErrs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return FlattenErrs(writeErrs)
|
||||
}
|
10
trunk/3rdparty/srs-bench/rtc/pion_util.go
vendored
Normal file
10
trunk/3rdparty/srs-bench/rtc/pion_util.go
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
package rtc
|
||||
|
||||
import "fmt"
|
||||
|
||||
func FlattenErrs(errors []error) error {
|
||||
if len(errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("%v", errors)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue