diff --git a/go.mod b/go.mod index 2ce78193..6bd7f381 100644 --- a/go.mod +++ b/go.mod @@ -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 ( 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 ( 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 diff --git a/go.sum b/go.sum index 7e6fb8a9..5ac2d537 100644 --- a/go.sum +++ b/go.sum @@ -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= 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+ 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= diff --git a/internal/core/hls_muxer.go b/internal/core/hls_muxer.go index e5a96fd6..ad1f5f51 100644 --- a/internal/core/hls_muxer.go +++ b/internal/core/hls_muxer.go @@ -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 { 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{}) 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{}) 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() { } // 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. diff --git a/internal/core/hls_source.go b/internal/core/hls_source.go index 8bffd8c7..5f98bd65 100644 --- a/internal/core/hls_source.go +++ b/internal/core/hls_source.go @@ -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 { 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 { } if stream != nil { - rtcpSenders.OnPacketRTP(trackID, payload) - stream.onPacketRTP(trackID, payload) + rtcpSenders.OnPacketRTP(trackID, pkt) + stream.onPacketRTP(trackID, pkt) } } diff --git a/internal/core/hls_source_test.go b/internal/core/hls_source_test.go index d2c0b41d..18bff390 100644 --- a/internal/core/hls_source_test.go +++ b/internal/core/hls_source_test.go @@ -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) }, diff --git a/internal/core/reader.go b/internal/core/reader.go index 826205e7..cd2490a8 100644 --- a/internal/core/reader.go +++ b/internal/core/reader.go @@ -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{} } diff --git a/internal/core/rtmp_conn.go b/internal/core/rtmp_conn.go index 497cabbf..fbc5c32e 100644 --- a/internal/core/rtmp_conn.go +++ b/internal/core/rtmp_conn.go @@ -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) { 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 { 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 { 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 { 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 { 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 { 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() { } // 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. diff --git a/internal/core/rtmp_source.go b/internal/core/rtmp_source.go index f807c433..18c68f70 100644 --- a/internal/core/rtmp_source.go +++ b/internal/core/rtmp_source.go @@ -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 { 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 { 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 { 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) } } } diff --git a/internal/core/rtsp_server_test.go b/internal/core/rtsp_server_test.go index de9cce22..d899dd6a 100644 --- a/internal/core/rtsp_server_test.go +++ b/internal/core/rtsp_server_test.go @@ -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) { 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) { 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) { } 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) } diff --git a/internal/core/rtsp_session.go b/internal/core/rtsp_session.go index ac44cff4..8a8e382b 100644 --- a/internal/core/rtsp_session.go +++ b/internal/core/rtsp_session.go @@ -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() { } // 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) { 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) return } - s.stream.onPacketRTCP(ctx.TrackID, ctx.Payload) + s.stream.onPacketRTCP(ctx.TrackID, ctx.Packet) } diff --git a/internal/core/rtsp_source.go b/internal/core/rtsp_source.go index 12711b7f..4c895d70 100644 --- a/internal/core/rtsp_source.go +++ b/internal/core/rtsp_source.go @@ -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 { 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 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 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 } } } 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) } } diff --git a/internal/core/rtsp_source_test.go b/internal/core/rtsp_source_test.go index e8cdbda6..238ab9dd 100644 --- a/internal/core/rtsp_source_test.go +++ b/internal/core/rtsp_source_test.go @@ -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) { 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) { 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) { 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 } diff --git a/internal/core/stream.go b/internal/core/stream.go index fd517375..c04e7db3 100644 --- a/internal/core/stream.go +++ b/internal/core/stream.go @@ -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) { 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) { } } -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) } diff --git a/internal/hls/client.go b/internal/hls/client.go index d47bbf79..98e0e431 100644 --- a/internal/hls/client.go +++ b/internal/hls/client.go @@ -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 { 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 { 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( 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 { 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 { 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( 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 { // 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( 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 { 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) } diff --git a/internal/hls/client_test.go b/internal/hls/client_test.go index ecf60a76..d22659c3 100644 --- a/internal/hls/client_test.go +++ b/internal/hls/client_test.go @@ -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) { 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{}, diff --git a/internal/rtcpsenderset/rtcpsenderset.go b/internal/rtcpsenderset/rtcpsenderset.go index 4812462a..3b81a720 100644 --- a/internal/rtcpsenderset/rtcpsenderset.go +++ b/internal/rtcpsenderset/rtcpsenderset.go @@ -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 { // 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() { } // 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) }