Browse Source

rtsp: parse all incoming RTP/RTCP packets

pull/858/head
aler9 5 years ago committed by Alessandro Ros
parent
commit
5504ff44b6
  1. 8
      go.mod
  2. 16
      go.sum
  3. 27
      internal/core/hls_muxer.go
  4. 7
      internal/core/hls_source.go
  5. 5
      internal/core/hls_source_test.go
  6. 9
      internal/core/reader.go
  7. 59
      internal/core/rtmp_conn.go
  8. 33
      internal/core/rtmp_source.go
  9. 33
      internal/core/rtsp_server_test.go
  10. 10
      internal/core/rtsp_session.go
  11. 25
      internal/core/rtsp_source.go
  12. 41
      internal/core/rtsp_source_test.go
  13. 22
      internal/core/stream.go
  14. 47
      internal/hls/client.go
  15. 5
      internal/hls/client_test.go
  16. 10
      internal/rtcpsenderset/rtcpsenderset.go

8
go.mod

@ -4,7 +4,7 @@ go 1.17 @@ -4,7 +4,7 @@ go 1.17
require (
code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5
github.com/aler9/gortsplib v0.0.0-20220213160013-a235613fd674
github.com/aler9/gortsplib v0.0.0-20220217230339-d44f1eb03a9f
github.com/asticode/go-astits v1.10.0
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.7.2
@ -12,8 +12,9 @@ require ( @@ -12,8 +12,9 @@ require (
github.com/grafov/m3u8 v0.11.1
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/notedit/rtmp v0.0.2
github.com/pion/rtp v1.6.2
github.com/stretchr/testify v1.6.1
github.com/pion/rtcp v1.2.9
github.com/pion/rtp v1.7.4
github.com/stretchr/testify v1.7.0
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/yaml.v2 v2.4.0
@ -36,7 +37,6 @@ require ( @@ -36,7 +37,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.4 // indirect
github.com/pion/sdp/v3 v3.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect

16
go.sum

@ -4,8 +4,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo @@ -4,8 +4,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aler9/gortsplib v0.0.0-20220213160013-a235613fd674 h1:06MThBlbTAfeJXy/49/SfYgdjF6XA5YSkg3nEWLn5ko=
github.com/aler9/gortsplib v0.0.0-20220213160013-a235613fd674/go.mod h1:fyQrQyHo8QvdR/h357tkv1g36VesZlzEPsdAu2VrHHc=
github.com/aler9/gortsplib v0.0.0-20220217230339-d44f1eb03a9f h1:NIH+yILuAy6RP6mjzt/c+dIBB23FDFK3hk29VfRByxk=
github.com/aler9/gortsplib v0.0.0-20220217230339-d44f1eb03a9f/go.mod h1:mst8cTkmxLn8Osiug8HBjMsNFRt0u7QHt5phJQ1tFVw=
github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927 h1:95mXJ5fUCYpBRdSOnLAQAdJHHKxxxJrVCiaqDi965YQ=
github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927/go.mod h1:vzuE21rowz+lT1NGsWbreIvYulgBpCGnQyeTyFblUHc=
github.com/asticode/go-astikit v0.20.0 h1:+7N+J4E4lWx2QOkRdOf6DafWJMv6O4RRfgClwQokrH8=
@ -82,11 +82,10 @@ github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= @@ -82,11 +82,10 @@ github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.4 h1:NT3H5LkUGgaEapvp0HGik+a+CpflRF7KTD7H+o7OWIM=
github.com/pion/rtcp v1.2.4/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
github.com/pion/rtp v1.6.1/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtp v1.6.2 h1:iGBerLX6JiDjB9NXuaPzHyxHFG9JsIEdgwTC0lp5n/U=
github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtcp v1.2.9 h1:1ujStwg++IOLIEoOiIQ2s+qBuJ1VN81KW+9pMPsif+U=
github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
github.com/pion/rtp v1.7.4 h1:4dMbjb1SuynU5OpA3kz1zHK+u+eOCQjW3MAeVHf1ODA=
github.com/pion/rtp v1.7.4/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/sdp/v3 v3.0.2 h1:UNnSPVaMM+Pdu/mR9UvAyyo6zkdYbKeuOooCwZvTl/g=
github.com/pion/sdp/v3 v3.0.2/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
@ -96,8 +95,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ @@ -96,8 +95,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=

27
internal/core/hls_muxer.go

@ -17,6 +17,7 @@ import ( @@ -17,6 +17,7 @@ import (
"github.com/aler9/gortsplib/pkg/ringbuffer"
"github.com/aler9/gortsplib/pkg/rtpaac"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/conf"
@ -109,7 +110,7 @@ type hlsMuxerRequest struct { @@ -109,7 +110,7 @@ type hlsMuxerRequest struct {
type hlsMuxerTrackIDPayloadPair struct {
trackID int
buf []byte
packet *rtp.Packet
}
type hlsMuxerPathManager interface {
@ -342,14 +343,7 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{}) @@ -342,14 +343,7 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{})
pair := data.(hlsMuxerTrackIDPayloadPair)
if videoTrack != nil && pair.trackID == videoTrackID {
var pkt rtp.Packet
err := pkt.Unmarshal(pair.buf)
if err != nil {
m.log(logger.Warn, "unable to decode RTP packet: %v", err)
continue
}
nalus, pts, err := h264Decoder.DecodeUntilMarker(&pkt)
nalus, pts, err := h264Decoder.DecodeUntilMarker(pair.packet)
if err != nil {
if err != rtph264.ErrMorePacketsNeeded &&
err != rtph264.ErrNonStartingPacketAndNoPrevious {
@ -364,14 +358,7 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{}) @@ -364,14 +358,7 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{})
continue
}
} else if audioTrack != nil && pair.trackID == audioTrackID {
var pkt rtp.Packet
err := pkt.Unmarshal(pair.buf)
if err != nil {
m.log(logger.Warn, "unable to decode RTP packet: %v", err)
continue
}
aus, pts, err := aacDecoder.Decode(&pkt)
aus, pts, err := aacDecoder.Decode(pair.packet)
if err != nil {
if err != rtpaac.ErrMorePacketsNeeded {
m.log(logger.Warn, "unable to decode audio track: %v", err)
@ -548,12 +535,12 @@ func (m *hlsMuxer) onReaderAccepted() { @@ -548,12 +535,12 @@ func (m *hlsMuxer) onReaderAccepted() {
}
// onReaderPacketRTP implements reader.
func (m *hlsMuxer) onReaderPacketRTP(trackID int, payload []byte) {
m.ringBuffer.Push(hlsMuxerTrackIDPayloadPair{trackID, payload})
func (m *hlsMuxer) onReaderPacketRTP(trackID int, pkt *rtp.Packet) {
m.ringBuffer.Push(hlsMuxerTrackIDPayloadPair{trackID, pkt})
}
// onReaderPacketRTCP implements reader.
func (m *hlsMuxer) onReaderPacketRTCP(trackID int, payload []byte) {
func (m *hlsMuxer) onReaderPacketRTCP(trackID int, pkt rtcp.Packet) {
}
// onReaderAPIDescribe implements reader.

7
internal/core/hls_source.go

@ -6,6 +6,7 @@ import ( @@ -6,6 +6,7 @@ import (
"time"
"github.com/aler9/gortsplib"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/hls"
"github.com/aler9/rtsp-simple-server/internal/logger"
@ -128,7 +129,7 @@ func (s *hlsSource) runInner() bool { @@ -128,7 +129,7 @@ func (s *hlsSource) runInner() bool {
return nil
}
onPacket := func(isVideo bool, payload []byte) {
onPacket := func(isVideo bool, pkt *rtp.Packet) {
var trackID int
if isVideo {
trackID = videoTrackID
@ -137,8 +138,8 @@ func (s *hlsSource) runInner() bool { @@ -137,8 +138,8 @@ func (s *hlsSource) runInner() bool {
}
if stream != nil {
rtcpSenders.OnPacketRTP(trackID, payload)
stream.onPacketRTP(trackID, payload)
rtcpSenders.OnPacketRTP(trackID, pkt)
stream.onPacketRTP(trackID, pkt)
}
}

5
internal/core/hls_source_test.go

@ -134,10 +134,7 @@ func TestHLSSource(t *testing.T) { @@ -134,10 +134,7 @@ func TestHLSSource(t *testing.T) {
frameRecv := make(chan struct{})
c := gortsplib.Client{
OnPacketRTP: func(trackID int, payload []byte) {
var pkt rtp.Packet
err := pkt.Unmarshal(payload)
require.NoError(t, err)
OnPacketRTP: func(trackID int, pkt *rtp.Packet) {
require.Equal(t, []byte{0x05}, pkt.Payload)
close(frameRecv)
},

9
internal/core/reader.go

@ -1,10 +1,15 @@ @@ -1,10 +1,15 @@
package core
import (
"github.com/pion/rtcp"
"github.com/pion/rtp"
)
// reader is an entity that can read a stream.
type reader interface {
close()
onReaderAccepted()
onReaderPacketRTP(int, []byte)
onReaderPacketRTCP(int, []byte)
onReaderPacketRTP(int, *rtp.Packet)
onReaderPacketRTCP(int, rtcp.Packet)
onReaderAPIDescribe() interface{}
}

59
internal/core/rtmp_conn.go

@ -16,6 +16,7 @@ import ( @@ -16,6 +16,7 @@ import (
"github.com/aler9/gortsplib/pkg/rtpaac"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/notedit/rtmp/av"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/conf"
@ -39,7 +40,7 @@ func pathNameAndQuery(inURL *url.URL) (string, url.Values, string) { @@ -39,7 +40,7 @@ func pathNameAndQuery(inURL *url.URL) (string, url.Values, string) {
type rtmpConnTrackIDPayloadPair struct {
trackID int
buf []byte
packet *rtp.Packet
}
type rtmpConnPathManager interface {
@ -330,14 +331,7 @@ func (c *rtmpConn) runRead(ctx context.Context) error { @@ -330,14 +331,7 @@ func (c *rtmpConn) runRead(ctx context.Context) error {
pair := data.(rtmpConnTrackIDPayloadPair)
if videoTrack != nil && pair.trackID == videoTrackID {
var pkt rtp.Packet
err := pkt.Unmarshal(pair.buf)
if err != nil {
c.log(logger.Warn, "unable to decode RTP packet: %v", err)
continue
}
nalus, pts, err := h264Decoder.DecodeUntilMarker(&pkt)
nalus, pts, err := h264Decoder.DecodeUntilMarker(pair.packet)
if err != nil {
if err != rtph264.ErrMorePacketsNeeded && err != rtph264.ErrNonStartingPacketAndNoPrevious {
c.log(logger.Warn, "unable to decode video track: %v", err)
@ -398,14 +392,7 @@ func (c *rtmpConn) runRead(ctx context.Context) error { @@ -398,14 +392,7 @@ func (c *rtmpConn) runRead(ctx context.Context) error {
return err
}
} else if audioTrack != nil && pair.trackID == audioTrackID {
var pkt rtp.Packet
err := pkt.Unmarshal(pair.buf)
if err != nil {
c.log(logger.Warn, "unable to decode RTP packet: %v", err)
continue
}
aus, pts, err := aacDecoder.Decode(&pkt)
aus, pts, err := aacDecoder.Decode(pair.packet)
if err != nil {
if err != rtpaac.ErrMorePacketsNeeded {
c.log(logger.Warn, "unable to decode audio track: %v", err)
@ -510,9 +497,9 @@ func (c *rtmpConn) runPublish(ctx context.Context) error { @@ -510,9 +497,9 @@ func (c *rtmpConn) runPublish(ctx context.Context) error {
rtcpSenders := rtcpsenderset.New(tracks, rres.stream.onPacketRTCP)
defer rtcpSenders.Close()
onPacketRTP := func(trackID int, payload []byte) {
rtcpSenders.OnPacketRTP(trackID, payload)
rres.stream.onPacketRTP(trackID, payload)
onPacketRTP := func(trackID int, pkt *rtp.Packet) {
rtcpSenders.OnPacketRTP(trackID, pkt)
rres.stream.onPacketRTP(trackID, pkt)
}
for {
@ -555,17 +542,8 @@ func (c *rtmpConn) runPublish(ctx context.Context) error { @@ -555,17 +542,8 @@ func (c *rtmpConn) runPublish(ctx context.Context) error {
return fmt.Errorf("error while encoding H264: %v", err)
}
bytss := make([][]byte, len(pkts))
for i, pkt := range pkts {
byts, err := pkt.Marshal()
if err != nil {
return fmt.Errorf("error while encoding H264: %v", err)
}
bytss[i] = byts
}
for _, byts := range bytss {
onPacketRTP(videoTrackID, byts)
for _, pkt := range pkts {
onPacketRTP(videoTrackID, pkt)
}
case av.AAC:
@ -578,17 +556,8 @@ func (c *rtmpConn) runPublish(ctx context.Context) error { @@ -578,17 +556,8 @@ func (c *rtmpConn) runPublish(ctx context.Context) error {
return fmt.Errorf("error while encoding AAC: %v", err)
}
bytss := make([][]byte, len(pkts))
for i, pkt := range pkts {
byts, err := pkt.Marshal()
if err != nil {
return fmt.Errorf("error while encoding AAC: %v", err)
}
bytss[i] = byts
}
for _, byts := range bytss {
onPacketRTP(audioTrackID, byts)
for _, pkt := range pkts {
onPacketRTP(audioTrackID, pkt)
}
}
}
@ -646,12 +615,12 @@ func (c *rtmpConn) onReaderAccepted() { @@ -646,12 +615,12 @@ func (c *rtmpConn) onReaderAccepted() {
}
// onReaderPacketRTP implements reader.
func (c *rtmpConn) onReaderPacketRTP(trackID int, payload []byte) {
c.ringBuffer.Push(rtmpConnTrackIDPayloadPair{trackID, payload})
func (c *rtmpConn) onReaderPacketRTP(trackID int, pkt *rtp.Packet) {
c.ringBuffer.Push(rtmpConnTrackIDPayloadPair{trackID, pkt})
}
// onReaderPacketRTCP implements reader.
func (c *rtmpConn) onReaderPacketRTCP(trackID int, payload []byte) {
func (c *rtmpConn) onReaderPacketRTCP(trackID int, pkt rtcp.Packet) {
}
// onReaderAPIDescribe implements reader.

33
internal/core/rtmp_source.go

@ -11,6 +11,7 @@ import ( @@ -11,6 +11,7 @@ import (
"github.com/aler9/gortsplib/pkg/rtpaac"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/notedit/rtmp/av"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/conf"
"github.com/aler9/rtsp-simple-server/internal/logger"
@ -164,9 +165,9 @@ func (s *rtmpSource) runInner() bool { @@ -164,9 +165,9 @@ func (s *rtmpSource) runInner() bool {
rtcpSenders := rtcpsenderset.New(tracks, res.stream.onPacketRTCP)
defer rtcpSenders.Close()
onPacketRTP := func(trackID int, payload []byte) {
rtcpSenders.OnPacketRTP(trackID, payload)
res.stream.onPacketRTP(trackID, payload)
onPacketRTP := func(trackID int, pkt *rtp.Packet) {
rtcpSenders.OnPacketRTP(trackID, pkt)
res.stream.onPacketRTP(trackID, pkt)
}
for {
@ -204,17 +205,8 @@ func (s *rtmpSource) runInner() bool { @@ -204,17 +205,8 @@ func (s *rtmpSource) runInner() bool {
return fmt.Errorf("error while encoding H264: %v", err)
}
bytss := make([][]byte, len(pkts))
for i, pkt := range pkts {
byts, err := pkt.Marshal()
if err != nil {
return fmt.Errorf("error while encoding H264: %v", err)
}
bytss[i] = byts
}
for _, byts := range bytss {
onPacketRTP(videoTrackID, byts)
for _, pkt := range pkts {
onPacketRTP(videoTrackID, pkt)
}
case av.AAC:
@ -227,17 +219,8 @@ func (s *rtmpSource) runInner() bool { @@ -227,17 +219,8 @@ func (s *rtmpSource) runInner() bool {
return fmt.Errorf("error while encoding AAC: %v", err)
}
bytss := make([][]byte, len(pkts))
for i, pkt := range pkts {
byts, err := pkt.Marshal()
if err != nil {
return fmt.Errorf("error while encoding AAC: %v", err)
}
bytss[i] = byts
}
for _, byts := range bytss {
onPacketRTP(audioTrackID, byts)
for _, pkt := range pkts {
onPacketRTP(audioTrackID, pkt)
}
}
}

33
internal/core/rtsp_server_test.go

@ -6,6 +6,7 @@ import ( @@ -6,6 +6,7 @@ import (
"time"
"github.com/aler9/gortsplib"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
)
@ -458,11 +459,11 @@ func TestRTSPServerPublisherOverride(t *testing.T) { @@ -458,11 +459,11 @@ func TestRTSPServerPublisherOverride(t *testing.T) {
frameRecv := make(chan struct{})
c := gortsplib.Client{
OnPacketRTP: func(trackID int, payload []byte) {
OnPacketRTP: func(trackID int, pkt *rtp.Packet) {
if ca == "enabled" {
require.Equal(t, []byte{0x05, 0x06, 0x07, 0x08}, payload)
require.Equal(t, []byte{0x05, 0x06, 0x07, 0x08}, pkt.Payload)
} else {
require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, payload)
require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, pkt.Payload)
}
close(frameRecv)
},
@ -472,8 +473,17 @@ func TestRTSPServerPublisherOverride(t *testing.T) { @@ -472,8 +473,17 @@ func TestRTSPServerPublisherOverride(t *testing.T) {
require.NoError(t, err)
defer c.Close()
err = s1.WritePacketRTP(0,
[]byte{0x01, 0x02, 0x03, 0x04})
err = s1.WritePacketRTP(0, &rtp.Packet{
Header: rtp.Header{
Version: 0x02,
PayloadType: 97,
SequenceNumber: 57899,
Timestamp: 345234345,
SSRC: 978651231,
Marker: true,
},
Payload: []byte{0x01, 0x02, 0x03, 0x04},
})
if ca == "enabled" {
require.Error(t, err)
} else {
@ -481,8 +491,17 @@ func TestRTSPServerPublisherOverride(t *testing.T) { @@ -481,8 +491,17 @@ func TestRTSPServerPublisherOverride(t *testing.T) {
}
if ca == "enabled" {
err = s2.WritePacketRTP(0,
[]byte{0x05, 0x06, 0x07, 0x08})
err = s2.WritePacketRTP(0, &rtp.Packet{
Header: rtp.Header{
Version: 0x02,
PayloadType: 97,
SequenceNumber: 57899,
Timestamp: 345234345,
SSRC: 978651231,
Marker: true,
},
Payload: []byte{0x05, 0x06, 0x07, 0x08},
})
require.NoError(t, err)
}

10
internal/core/rtsp_session.go

@ -9,6 +9,8 @@ import ( @@ -9,6 +9,8 @@ import (
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/base"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/conf"
"github.com/aler9/rtsp-simple-server/internal/externalcmd"
@ -345,12 +347,12 @@ func (s *rtspSession) onReaderAccepted() { @@ -345,12 +347,12 @@ func (s *rtspSession) onReaderAccepted() {
}
// onReaderPacketRTP implements reader.
func (s *rtspSession) onReaderPacketRTP(trackID int, payload []byte) {
func (s *rtspSession) onReaderPacketRTP(trackID int, pkt *rtp.Packet) {
// packets are routed to the session by gortsplib.ServerStream.
}
// onReaderPacketRTCP implements reader.
func (s *rtspSession) onReaderPacketRTCP(trackID int, payload []byte) {
func (s *rtspSession) onReaderPacketRTCP(trackID int, pkt rtcp.Packet) {
// packets are routed to the session by gortsplib.ServerStream.
}
@ -404,7 +406,7 @@ func (s *rtspSession) onPacketRTP(ctx *gortsplib.ServerHandlerOnPacketRTPCtx) { @@ -404,7 +406,7 @@ func (s *rtspSession) onPacketRTP(ctx *gortsplib.ServerHandlerOnPacketRTPCtx) {
return
}
s.stream.onPacketRTP(ctx.TrackID, ctx.Payload)
s.stream.onPacketRTP(ctx.TrackID, ctx.Packet)
}
// onPacketRTCP is called by rtspServer.
@ -413,5 +415,5 @@ func (s *rtspSession) onPacketRTCP(ctx *gortsplib.ServerHandlerOnPacketRTCPCtx) @@ -413,5 +415,5 @@ func (s *rtspSession) onPacketRTCP(ctx *gortsplib.ServerHandlerOnPacketRTCPCtx)
return
}
s.stream.onPacketRTCP(ctx.TrackID, ctx.Payload)
s.stream.onPacketRTCP(ctx.TrackID, ctx.Packet)
}

25
internal/core/rtsp_source.go

@ -14,6 +14,7 @@ import ( @@ -14,6 +14,7 @@ import (
"github.com/aler9/gortsplib/pkg/base"
"github.com/aler9/gortsplib/pkg/h264"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/conf"
@ -209,12 +210,12 @@ func (s *rtspSource) runInner() bool { @@ -209,12 +210,12 @@ func (s *rtspSource) runInner() bool {
s.parent.onSourceStaticSetNotReady(pathSourceStaticSetNotReadyReq{source: s})
}()
c.OnPacketRTP = func(trackID int, payload []byte) {
res.stream.onPacketRTP(trackID, payload)
c.OnPacketRTP = func(trackID int, pkt *rtp.Packet) {
res.stream.onPacketRTP(trackID, pkt)
}
c.OnPacketRTCP = func(trackID int, payload []byte) {
res.stream.onPacketRTCP(trackID, payload)
c.OnPacketRTCP = func(trackID int, pkt rtcp.Packet) {
res.stream.onPacketRTCP(trackID, pkt)
}
_, err = c.Play(nil)
@ -267,7 +268,7 @@ func (s *rtspSource) handleMissingH264Params(c *gortsplib.Client, tracks gortspl @@ -267,7 +268,7 @@ func (s *rtspSource) handleMissingH264Params(c *gortsplib.Client, tracks gortspl
var pps []byte
paramsReceived := make(chan struct{})
c.OnPacketRTP = func(trackID int, payload []byte) {
c.OnPacketRTP = func(trackID int, pkt *rtp.Packet) {
streamMutex.RLock()
defer streamMutex.RUnlock()
@ -282,13 +283,7 @@ func (s *rtspSource) handleMissingH264Params(c *gortsplib.Client, tracks gortspl @@ -282,13 +283,7 @@ func (s *rtspSource) handleMissingH264Params(c *gortsplib.Client, tracks gortspl
default:
}
var pkt rtp.Packet
err := pkt.Unmarshal(payload)
if err != nil {
return
}
nalus, _, err := decoder.Decode(&pkt)
nalus, _, err := decoder.Decode(pkt)
if err != nil {
return
}
@ -310,16 +305,16 @@ func (s *rtspSource) handleMissingH264Params(c *gortsplib.Client, tracks gortspl @@ -310,16 +305,16 @@ func (s *rtspSource) handleMissingH264Params(c *gortsplib.Client, tracks gortspl
}
}
} else {
stream.onPacketRTP(trackID, payload)
stream.onPacketRTP(trackID, pkt)
}
}
c.OnPacketRTCP = func(trackID int, payload []byte) {
c.OnPacketRTCP = func(trackID int, pkt rtcp.Packet) {
streamMutex.RLock()
defer streamMutex.RUnlock()
if stream != nil {
stream.onPacketRTCP(trackID, payload)
stream.onPacketRTCP(trackID, pkt)
}
}

41
internal/core/rtsp_source_test.go

@ -74,7 +74,17 @@ func TestRTSPSource(t *testing.T) { @@ -74,7 +74,17 @@ func TestRTSPSource(t *testing.T) {
onPlay: func(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Response, error) {
go func() {
time.Sleep(1 * time.Second)
stream.WritePacketRTP(0, []byte{0x01, 0x02, 0x03, 0x04})
stream.WritePacketRTP(0, &rtp.Packet{
Header: rtp.Header{
Version: 0x02,
PayloadType: 97,
SequenceNumber: 57899,
Timestamp: 345234345,
SSRC: 978651231,
Marker: true,
},
Payload: []byte{0x01, 0x02, 0x03, 0x04},
})
}()
return &base.Response{
@ -133,8 +143,8 @@ func TestRTSPSource(t *testing.T) { @@ -133,8 +143,8 @@ func TestRTSPSource(t *testing.T) {
received := make(chan struct{})
c := gortsplib.Client{
OnPacketRTP: func(trackID int, payload []byte) {
require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, payload)
OnPacketRTP: func(trackID int, pkt *rtp.Packet) {
require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, pkt.Payload)
close(received)
},
}
@ -232,30 +242,25 @@ func TestRTSPSourceMissingH264Params(t *testing.T) { @@ -232,30 +242,25 @@ func TestRTSPSourceMissingH264Params(t *testing.T) {
pkts, err := enc.Encode([][]byte{{5}}, 0) // IDR
require.NoError(t, err)
byts, _ := pkts[0].Marshal()
stream.WritePacketRTP(0, byts)
stream.WritePacketRTP(0, pkts[0])
pkts, err = enc.Encode([][]byte{{7, 1, 2, 3}}, 0) // SPS
require.NoError(t, err)
byts, _ = pkts[0].Marshal()
stream.WritePacketRTP(0, byts)
stream.WritePacketRTP(0, pkts[0])
pkts, err = enc.Encode([][]byte{{8}}, 0) // PPS
require.NoError(t, err)
byts, _ = pkts[0].Marshal()
stream.WritePacketRTP(0, byts)
stream.WritePacketRTP(0, pkts[0])
pkts, err = enc.Encode([][]byte{{5, 1}}, 0) // IDR
require.NoError(t, err)
byts, _ = pkts[0].Marshal()
stream.WritePacketRTP(0, byts)
stream.WritePacketRTP(0, pkts[0])
time.Sleep(500 * time.Millisecond)
pkts, err = enc.Encode([][]byte{{5, 2}}, 0) // IDR
require.NoError(t, err)
byts, _ = pkts[0].Marshal()
stream.WritePacketRTP(0, byts)
stream.WritePacketRTP(0, pkts[0])
}()
return &base.Response{
@ -283,14 +288,8 @@ func TestRTSPSourceMissingH264Params(t *testing.T) { @@ -283,14 +288,8 @@ func TestRTSPSourceMissingH264Params(t *testing.T) {
decoder := rtph264.NewDecoder()
c := gortsplib.Client{
OnPacketRTP: func(trackID int, payload []byte) {
var pkt rtp.Packet
err := pkt.Unmarshal(payload)
if err != nil {
return
}
nalus, _, err := decoder.Decode(&pkt)
OnPacketRTP: func(trackID int, pkt *rtp.Packet) {
nalus, _, err := decoder.Decode(pkt)
if err != nil {
return
}

22
internal/core/stream.go

@ -4,6 +4,8 @@ import ( @@ -4,6 +4,8 @@ import (
"sync"
"github.com/aler9/gortsplib"
"github.com/pion/rtcp"
"github.com/pion/rtp"
)
type streamNonRTSPReadersMap struct {
@ -35,21 +37,21 @@ func (m *streamNonRTSPReadersMap) remove(r reader) { @@ -35,21 +37,21 @@ func (m *streamNonRTSPReadersMap) remove(r reader) {
delete(m.ma, r)
}
func (m *streamNonRTSPReadersMap) forwardPacketRTP(trackID int, payload []byte) {
func (m *streamNonRTSPReadersMap) forwardPacketRTP(trackID int, pkt *rtp.Packet) {
m.mutex.RLock()
defer m.mutex.RUnlock()
for c := range m.ma {
c.onReaderPacketRTP(trackID, payload)
c.onReaderPacketRTP(trackID, pkt)
}
}
func (m *streamNonRTSPReadersMap) forwardPacketRTCP(trackID int, payload []byte) {
func (m *streamNonRTSPReadersMap) forwardPacketRTCP(trackID int, pkt rtcp.Packet) {
m.mutex.RLock()
defer m.mutex.RUnlock()
for c := range m.ma {
c.onReaderPacketRTCP(trackID, payload)
c.onReaderPacketRTCP(trackID, pkt)
}
}
@ -87,18 +89,18 @@ func (s *stream) readerRemove(r reader) { @@ -87,18 +89,18 @@ func (s *stream) readerRemove(r reader) {
}
}
func (s *stream) onPacketRTP(trackID int, payload []byte) {
func (s *stream) onPacketRTP(trackID int, pkt *rtp.Packet) {
// forward to RTSP readers
s.rtspStream.WritePacketRTP(trackID, payload)
s.rtspStream.WritePacketRTP(trackID, pkt)
// forward to non-RTSP readers
s.nonRTSPReaders.forwardPacketRTP(trackID, payload)
s.nonRTSPReaders.forwardPacketRTP(trackID, pkt)
}
func (s *stream) onPacketRTCP(trackID int, payload []byte) {
func (s *stream) onPacketRTCP(trackID int, pkt rtcp.Packet) {
// forward to RTSP readers
s.rtspStream.WritePacketRTCP(trackID, payload)
s.rtspStream.WritePacketRTCP(trackID, pkt)
// forward to non-RTSP readers
s.nonRTSPReaders.forwardPacketRTCP(trackID, payload)
s.nonRTSPReaders.forwardPacketRTCP(trackID, pkt)
}

47
internal/hls/client.go

@ -22,6 +22,7 @@ import ( @@ -22,6 +22,7 @@ import (
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/asticode/go-astits"
"github.com/grafov/m3u8"
"github.com/pion/rtp"
"github.com/aler9/rtsp-simple-server/internal/logger"
)
@ -135,7 +136,7 @@ type clientVideoProcessorData struct { @@ -135,7 +136,7 @@ type clientVideoProcessorData struct {
type clientVideoProcessor struct {
ctx context.Context
onTrack func(gortsplib.Track) error
onPacket func([]byte)
onPacket func(*rtp.Packet)
queue chan clientVideoProcessorData
sps []byte
@ -147,7 +148,7 @@ type clientVideoProcessor struct { @@ -147,7 +148,7 @@ type clientVideoProcessor struct {
func newClientVideoProcessor(
ctx context.Context,
onTrack func(gortsplib.Track) error,
onPacket func([]byte),
onPacket func(*rtp.Packet),
) *clientVideoProcessor {
p := &clientVideoProcessor{
ctx: ctx,
@ -249,17 +250,8 @@ func (p *clientVideoProcessor) doProcess( @@ -249,17 +250,8 @@ func (p *clientVideoProcessor) doProcess(
return fmt.Errorf("error while encoding H264: %v", err)
}
bytss := make([][]byte, len(pkts))
for i, pkt := range pkts {
byts, err := pkt.Marshal()
if err != nil {
return fmt.Errorf("error while encoding H264: %v", err)
}
bytss[i] = byts
}
for _, byts := range bytss {
p.onPacket(byts)
for _, pkt := range pkts {
p.onPacket(pkt)
}
return nil
@ -291,7 +283,7 @@ type clientAudioProcessorData struct { @@ -291,7 +283,7 @@ type clientAudioProcessorData struct {
type clientAudioProcessor struct {
ctx context.Context
onTrack func(gortsplib.Track) error
onPacket func([]byte)
onPacket func(*rtp.Packet)
queue chan clientAudioProcessorData
encoder *rtpaac.Encoder
@ -301,7 +293,7 @@ type clientAudioProcessor struct { @@ -301,7 +293,7 @@ type clientAudioProcessor struct {
func newClientAudioProcessor(
ctx context.Context,
onTrack func(gortsplib.Track) error,
onPacket func([]byte),
onPacket func(*rtp.Packet),
) *clientAudioProcessor {
p := &clientAudioProcessor{
ctx: ctx,
@ -376,17 +368,8 @@ func (p *clientAudioProcessor) doProcess( @@ -376,17 +368,8 @@ func (p *clientAudioProcessor) doProcess(
return fmt.Errorf("error while encoding AAC: %v", err)
}
bytss := make([][]byte, len(pkts))
for i, pkt := range pkts {
byts, err := pkt.Marshal()
if err != nil {
return fmt.Errorf("error while encoding AAC: %v", err)
}
bytss[i] = byts
}
for _, byts := range bytss {
p.onPacket(byts)
for _, pkt := range pkts {
p.onPacket(pkt)
}
return nil
@ -409,7 +392,7 @@ type ClientParent interface { @@ -409,7 +392,7 @@ type ClientParent interface {
// Client is a HLS client.
type Client struct {
onTracks func(gortsplib.Track, gortsplib.Track) error
onPacket func(bool, []byte)
onPacket func(bool, *rtp.Packet)
parent ClientParent
ctx context.Context
@ -445,7 +428,7 @@ func NewClient( @@ -445,7 +428,7 @@ func NewClient(
primaryPlaylistURLStr string,
fingerprint string,
onTracks func(gortsplib.Track, gortsplib.Track) error,
onPacket func(bool, []byte),
onPacket func(bool, *rtp.Packet),
parent ClientParent,
) (*Client, error) {
primaryPlaylistURL, err := url.Parse(primaryPlaylistURLStr)
@ -909,16 +892,16 @@ func (c *Client) initializeEncoders() error { @@ -909,16 +892,16 @@ func (c *Client) initializeEncoders() error {
return c.onTracks(c.videoTrack, c.audioTrack)
}
func (c *Client) onVideoPacket(payload []byte) {
func (c *Client) onVideoPacket(pkt *rtp.Packet) {
c.tracksMutex.RLock()
defer c.tracksMutex.RUnlock()
c.onPacket(true, payload)
c.onPacket(true, pkt)
}
func (c *Client) onAudioPacket(payload []byte) {
func (c *Client) onAudioPacket(pkt *rtp.Packet) {
c.tracksMutex.RLock()
defer c.tracksMutex.RUnlock()
c.onPacket(false, payload)
c.onPacket(false, pkt)
}

5
internal/hls/client_test.go

@ -15,6 +15,7 @@ import ( @@ -15,6 +15,7 @@ import (
"github.com/aler9/gortsplib/pkg/h264"
"github.com/asticode/go-astits"
"github.com/gin-gonic/gin"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
"github.com/aler9/rtsp-simple-server/internal/logger"
@ -206,9 +207,9 @@ func TestClient(t *testing.T) { @@ -206,9 +207,9 @@ func TestClient(t *testing.T) {
func(gortsplib.Track, gortsplib.Track) error {
return nil
},
func(isVideo bool, byts []byte) {
func(isVideo bool, pkt *rtp.Packet) {
require.Equal(t, true, isVideo)
require.Equal(t, byte(0x05), byts[12])
require.Equal(t, []byte{0x05}, pkt.Payload)
close(packetRecv)
},
testLogger{},

10
internal/rtcpsenderset/rtcpsenderset.go

@ -5,11 +5,13 @@ import ( @@ -5,11 +5,13 @@ import (
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtcpsender"
"github.com/pion/rtcp"
"github.com/pion/rtp"
)
// RTCPSenderSet is a set of RTCP senders.
type RTCPSenderSet struct {
onPacketRTCP func(int, []byte)
onPacketRTCP func(int, rtcp.Packet)
senders []*rtcpsender.RTCPSender
// in
@ -22,7 +24,7 @@ type RTCPSenderSet struct { @@ -22,7 +24,7 @@ type RTCPSenderSet struct {
// New allocates a RTCPSenderSet.
func New(
tracks gortsplib.Tracks,
onPacketRTCP func(int, []byte),
onPacketRTCP func(int, rtcp.Packet),
) *RTCPSenderSet {
s := &RTCPSenderSet{
onPacketRTCP: onPacketRTCP,
@ -71,6 +73,6 @@ func (s *RTCPSenderSet) run() { @@ -71,6 +73,6 @@ func (s *RTCPSenderSet) run() {
}
// OnPacketRTP sends a RTP packet to the senders.
func (s *RTCPSenderSet) OnPacketRTP(trackID int, payload []byte) {
s.senders[trackID].ProcessPacketRTP(time.Now(), payload)
func (s *RTCPSenderSet) OnPacketRTP(trackID int, pkt *rtp.Packet) {
s.senders[trackID].ProcessPacketRTP(time.Now(), pkt)
}

Loading…
Cancel
Save