Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new APIs to enable simulcast probes without dropping packets #276

Open
wants to merge 3 commits into
base: v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"sync"
"time"

"github.com/pion/logging"

Check failure on line 13 in session.go

View workflow job for this annotation

GitHub Actions / lint / Go

import 'github.com/pion/logging' is not allowed from list 'Main' (depguard)
"github.com/pion/transport/v2/packetio"

Check failure on line 14 in session.go

View workflow job for this annotation

GitHub Actions / lint / Go

import 'github.com/pion/transport/v2/packetio' is not allowed from list 'Main' (depguard)
)

type streamSession interface {
Expand All @@ -20,12 +20,17 @@
decrypt([]byte) error
}

type newStream struct {
readStream readStream
payloadType uint8
}

type session struct {
localContextMutex sync.Mutex
localContext, remoteContext *Context
localOptions, remoteOptions []ContextOption

newStream chan readStream
newStream chan newStream
acceptStreamTimeout time.Time

started chan interface{}
Expand Down
10 changes: 5 additions & 5 deletions session_srtcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"net"
"time"

"github.com/pion/logging"

Check failure on line 10 in session_srtcp.go

View workflow job for this annotation

GitHub Actions / lint / Go

import 'github.com/pion/logging' is not allowed from list 'Main' (depguard)
"github.com/pion/rtcp"

Check failure on line 11 in session_srtcp.go

View workflow job for this annotation

GitHub Actions / lint / Go

import 'github.com/pion/rtcp' is not allowed from list 'Main' (depguard)
)

const defaultSessionSRTCPReplayProtectionWindow = 64
Expand Down Expand Up @@ -53,7 +53,7 @@
localOptions: localOpts,
remoteOptions: remoteOpts,
readStreams: map[uint32]readStream{},
newStream: make(chan readStream),
newStream: make(chan newStream),
acceptStreamTimeout: config.AcceptStreamTimeout,
started: make(chan interface{}),
closed: make(chan interface{}),
Expand Down Expand Up @@ -93,17 +93,17 @@

// AcceptStream returns a stream to handle RTCP for a single SSRC
func (s *SessionSRTCP) AcceptStream() (*ReadStreamSRTCP, uint32, error) {
stream, ok := <-s.newStream
newStream, ok := <-s.newStream
if !ok {
return nil, 0, errStreamAlreadyClosed
}

readStream, ok := stream.(*ReadStreamSRTCP)
readStream, ok := newStream.readStream.(*ReadStreamSRTCP)
if !ok {
return nil, 0, errFailedTypeAssertion
}

return readStream, stream.GetSSRC(), nil
return readStream, readStream.GetSSRC(), nil
}

// Close ends the session
Expand Down Expand Up @@ -172,7 +172,7 @@
if !s.session.acceptStreamTimeout.IsZero() {
_ = s.session.nextConn.SetReadDeadline(time.Time{})
}
s.session.newStream <- r // Notify AcceptStream
s.session.newStream <- newStream{readStream: r} // Notify AcceptStream
}

readStream, ok := r.(*ReadStreamSRTCP)
Expand Down
24 changes: 16 additions & 8 deletions session_srtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"sync"
"time"

"github.com/pion/logging"

Check failure on line 11 in session_srtp.go

View workflow job for this annotation

GitHub Actions / lint / Go

import 'github.com/pion/logging' is not allowed from list 'Main' (depguard)
"github.com/pion/rtp"

Check failure on line 12 in session_srtp.go

View workflow job for this annotation

GitHub Actions / lint / Go

import 'github.com/pion/rtp' is not allowed from list 'Main' (depguard)
)

const defaultSessionSRTPReplayProtectionWindow = 64
Expand Down Expand Up @@ -54,7 +54,7 @@
localOptions: localOpts,
remoteOptions: remoteOpts,
readStreams: map[uint32]readStream{},
newStream: make(chan readStream),
newStream: make(chan newStream),
acceptStreamTimeout: config.AcceptStreamTimeout,
started: make(chan interface{}),
closed: make(chan interface{}),
Expand Down Expand Up @@ -93,19 +93,26 @@
return nil, errFailedTypeAssertion
}

// AcceptStream returns a stream to handle RTCP for a single SSRC
// AcceptStream returns a stream to handle RTP for a single SSRC
func (s *SessionSRTP) AcceptStream() (*ReadStreamSRTP, uint32, error) {
stream, ok := <-s.newStream
readStream, ssrc, _, err := s.AcceptStreamWithPayloadType()
return readStream, ssrc, err
}

// AcceptStreamWithPayloadType returns a stream to handle RTP for a single SSRC.
// It returns the payload type as well as the SSRC.
func (s *SessionSRTP) AcceptStreamWithPayloadType() (*ReadStreamSRTP, uint32, uint8, error) {
newStream, ok := <-s.newStream
if !ok {
return nil, 0, errStreamAlreadyClosed
return nil, 0, 0, errStreamAlreadyClosed
}

readStream, ok := stream.(*ReadStreamSRTP)
readStream, ok := newStream.readStream.(*ReadStreamSRTP)
if !ok {
return nil, 0, errFailedTypeAssertion
return nil, 0, 0, errFailedTypeAssertion

Check warning on line 112 in session_srtp.go

View check run for this annotation

Codecov / codecov/patch

session_srtp.go#L112

Added line #L112 was not covered by tests
}

return readStream, stream.GetSSRC(), nil
return readStream, readStream.GetSSRC(), newStream.payloadType, nil
}

// Close ends the session
Expand Down Expand Up @@ -178,7 +185,8 @@
if !s.session.acceptStreamTimeout.IsZero() {
_ = s.session.nextConn.SetReadDeadline(time.Time{})
}
s.session.newStream <- r // Notify AcceptStream
// notify AcceptStream
s.session.newStream <- newStream{readStream: r, payloadType: h.PayloadType}
}

readStream, ok := r.(*ReadStreamSRTP)
Expand Down
40 changes: 40 additions & 0 deletions stream_srtp.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"errors"
"io"
"sync"
"sync/atomic"
"time"

"github.com/pion/rtp"
Expand All @@ -27,6 +28,10 @@
isInited bool

buffer io.ReadWriteCloser

peekedPacket []byte
peekedPacketMu sync.Mutex
peekedPacketPresent atomic.Bool
}

// Used by getOrCreateReadStream
Expand Down Expand Up @@ -74,8 +79,43 @@
return n, err
}

// Peek reads the next full RTP packet from the nextConn, but queues it internally.
// The next call to Read (or the next call to Peek without a call to Read in between)
// will return the same packet again.
func (r *ReadStreamSRTP) Peek(buf []byte) (int, error) {
r.peekedPacketMu.Lock()
defer r.peekedPacketMu.Unlock()
if r.peekedPacketPresent.Load() {
return copy(buf, r.peekedPacket), nil

Check warning on line 89 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L85-L89

Added lines #L85 - L89 were not covered by tests
}
n, err := r.buffer.Read(buf)
if err != nil {
return n, err

Check warning on line 93 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L91-L93

Added lines #L91 - L93 were not covered by tests
}
if cap(r.peekedPacket) < n {
size := 1500
if size < n {
size = n

Check warning on line 98 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L95-L98

Added lines #L95 - L98 were not covered by tests
}
r.peekedPacket = make([]byte, size)

Check warning on line 100 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L100

Added line #L100 was not covered by tests
}
r.peekedPacket = r.peekedPacket[:n]
copy(r.peekedPacket, buf)
r.peekedPacketPresent.Store(true)
return n, nil

Check warning on line 105 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L102-L105

Added lines #L102 - L105 were not covered by tests
}

// Read reads and decrypts full RTP packet from the nextConn
func (r *ReadStreamSRTP) Read(buf []byte) (int, error) {
if r.peekedPacketPresent.Load() {
r.peekedPacketMu.Lock()
if r.peekedPacketPresent.Swap(false) {
n := copy(buf, r.peekedPacket)
r.peekedPacketMu.Unlock()
return n, nil

Check warning on line 115 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L111-L115

Added lines #L111 - L115 were not covered by tests
}
r.peekedPacketMu.Unlock()

Check warning on line 117 in stream_srtp.go

View check run for this annotation

Codecov / codecov/patch

stream_srtp.go#L117

Added line #L117 was not covered by tests
}
return r.buffer.Read(buf)
}

Expand Down
Loading