Browse Source

update gortsplib

pull/1003/head
aler9 3 years ago
parent
commit
ec4c40b222
  1. 2
      go.mod
  2. 4
      go.sum
  3. 24
      internal/core/api_test.go
  4. 37
      internal/core/core_test.go
  5. 8
      internal/core/hls_muxer.go
  6. 8
      internal/core/metrics_test.go
  7. 12
      internal/core/rtmp_conn.go
  8. 58
      internal/core/rtsp_server_test.go
  9. 31
      internal/core/rtsp_source_test.go
  10. 10
      internal/core/stream.go
  11. 11
      internal/hls/client_audio_processor.go
  12. 7
      internal/hls/client_video_processor.go
  13. 4
      internal/hls/muxer_primary_playlist.go
  14. 57
      internal/hls/muxer_test.go
  15. 4
      internal/hls/muxer_variant_fmp4.go
  16. 14
      internal/hls/muxer_variant_fmp4_init.go
  17. 4
      internal/hls/muxer_variant_fmp4_segmenter.go
  18. 6
      internal/hls/muxer_variant_mpegts_segment.go
  19. 32
      internal/rtmp/conn.go
  20. 89
      internal/rtmp/conn_test.go

2
go.mod

@ -5,7 +5,7 @@ go 1.17 @@ -5,7 +5,7 @@ go 1.17
require (
code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5
github.com/abema/go-mp4 v0.7.2
github.com/aler9/gortsplib v0.0.0-20220622212730-fa36721df4d9
github.com/aler9/gortsplib v0.0.0-20220623113557-d80977dbaea3
github.com/asticode/go-astits v1.10.1-0.20220319093903-4abe66a9b757
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.8.1

4
go.sum

@ -6,8 +6,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo @@ -6,8 +6,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-20220622212730-fa36721df4d9 h1:hBVZrBdtxyn1dJTpvLpIvTkKjD8NfoGncBnfIaJqsOc=
github.com/aler9/gortsplib v0.0.0-20220622212730-fa36721df4d9/go.mod h1:i1e4CEs42IrbidMUNTSNOKmeGPCOHVX9P3BvPxzyMtI=
github.com/aler9/gortsplib v0.0.0-20220623113557-d80977dbaea3 h1:4kPboldLlj92Qr+LOoj3F+syP5k/dgW4EZhC1NfGeLc=
github.com/aler9/gortsplib v0.0.0-20220623113557-d80977dbaea3/go.mod h1:i1e4CEs42IrbidMUNTSNOKmeGPCOHVX9P3BvPxzyMtI=
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/aler9/writerseeker v0.0.0-20220601075008-6f0e685b9c82 h1:9WgSzBLo3a9ToSVV7sRTBYZ1GGOZUpq4+5H3SN0UZq4=

24
internal/core/api_test.go

@ -185,9 +185,11 @@ func TestAPIPathsList(t *testing.T) { @@ -185,9 +185,11 @@ func TestAPIPathsList(t *testing.T) {
_, ok = out.Items["mypath"]
require.Equal(t, true, ok)
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
func() {
source := gortsplib.Client{}
@ -250,9 +252,11 @@ func TestAPIList(t *testing.T) { @@ -250,9 +252,11 @@ func TestAPIList(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
switch ca {
case "rtsp":
@ -381,9 +385,11 @@ func TestAPIKick(t *testing.T) { @@ -381,9 +385,11 @@ func TestAPIKick(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
switch ca {
case "rtsp":

37
internal/core/core_test.go

@ -247,15 +247,15 @@ func main() { @@ -247,15 +247,15 @@ func main() {
panic("environment not set")
}
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
if err != nil {
panic(err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
source := gortsplib.Client{}
err = source.StartPublishing(
err := source.StartPublishing(
"rtsp://localhost:" + os.Getenv("RTSP_PORT") + "/" + os.Getenv("RTSP_PATH"),
gortsplib.Tracks{track})
if err != nil {
@ -376,13 +376,16 @@ func TestCorePathRunOnReady(t *testing.T) { @@ -376,13 +376,16 @@ func TestCorePathRunOnReady(t *testing.T) {
doneFile))
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
c := gortsplib.Client{}
err = c.StartPublishing(
err := c.StartPublishing(
"rtsp://localhost:8554/test",
gortsplib.Tracks{track})
require.NoError(t, err)
@ -410,9 +413,11 @@ func TestCoreHotReloading(t *testing.T) { @@ -410,9 +413,11 @@ func TestCoreHotReloading(t *testing.T) {
defer p.close()
func() {
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
c := gortsplib.Client{}
@ -430,9 +435,11 @@ func TestCoreHotReloading(t *testing.T) { @@ -430,9 +435,11 @@ func TestCoreHotReloading(t *testing.T) {
time.Sleep(1 * time.Second)
func() {
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
conn := gortsplib.Client{}

8
internal/core/hls_muxer.go

@ -311,10 +311,10 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{}) @@ -311,10 +311,10 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{})
audioTrack = tt
audioTrackID = i
aacDecoder = &rtpaac.Decoder{
SampleRate: tt.ClockRate(),
SizeLength: tt.SizeLength(),
IndexLength: tt.IndexLength(),
IndexDeltaLength: tt.IndexDeltaLength(),
SampleRate: tt.SampleRate,
SizeLength: tt.SizeLength,
IndexLength: tt.IndexLength,
IndexDeltaLength: tt.IndexDeltaLength,
}
aacDecoder.Init()
}

8
internal/core/metrics_test.go

@ -29,9 +29,11 @@ func TestMetrics(t *testing.T) { @@ -29,9 +29,11 @@ func TestMetrics(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
source := gortsplib.Client{}

12
internal/core/rtmp_conn.go

@ -278,10 +278,10 @@ func (c *rtmpConn) runRead(ctx context.Context) error { @@ -278,10 +278,10 @@ func (c *rtmpConn) runRead(ctx context.Context) error {
audioTrack = tt
audioTrackID = i
aacDecoder = &rtpaac.Decoder{
SampleRate: tt.ClockRate(),
SizeLength: tt.SizeLength(),
IndexLength: tt.IndexLength(),
IndexDeltaLength: tt.IndexDeltaLength(),
SampleRate: tt.SampleRate,
SizeLength: tt.SizeLength,
IndexLength: tt.IndexLength,
IndexDeltaLength: tt.IndexDeltaLength,
}
aacDecoder.Init()
}
@ -405,8 +405,8 @@ func (c *rtmpConn) runRead(ctx context.Context) error { @@ -405,8 +405,8 @@ func (c *rtmpConn) runRead(ctx context.Context) error {
// insert a H264DecoderConfig before every IDR
if idrPresent {
sps := videoTrack.SPS()
pps := videoTrack.PPS()
sps := videoTrack.SafeSPS()
pps := videoTrack.SafePPS()
codec := nh264.Codec{
SPS: map[int][]byte{

58
internal/core/rtsp_server_test.go

@ -230,13 +230,15 @@ func TestRTSPServerAuth(t *testing.T) { @@ -230,13 +230,15 @@ func TestRTSPServerAuth(t *testing.T) {
require.NoError(t, err)
}
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
source := gortsplib.Client{}
err = source.StartPublishing(
err := source.StartPublishing(
"rtsp://testpublisher:testpass@127.0.0.1:8554/teststream?param=value",
gortsplib.Tracks{track})
require.NoError(t, err)
@ -268,13 +270,15 @@ func TestRTSPServerAuth(t *testing.T) { @@ -268,13 +270,15 @@ func TestRTSPServerAuth(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
source := gortsplib.Client{}
err = source.StartPublishing(
err := source.StartPublishing(
"rtsp://testuser:testpass@127.0.0.1:8554/test/stream",
gortsplib.Tracks{track})
require.NoError(t, err)
@ -314,13 +318,15 @@ func TestRTSPServerAuthFail(t *testing.T) { @@ -314,13 +318,15 @@ func TestRTSPServerAuthFail(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
c := gortsplib.Client{}
err = c.StartPublishing(
err := c.StartPublishing(
"rtsp://"+ca.user+":"+ca.pass+"@localhost:8554/test/stream",
gortsplib.Tracks{track},
)
@ -377,13 +383,15 @@ func TestRTSPServerAuthFail(t *testing.T) { @@ -377,13 +383,15 @@ func TestRTSPServerAuthFail(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
c := gortsplib.Client{}
err = c.StartPublishing(
err := c.StartPublishing(
"rtsp://localhost:8554/test/stream",
gortsplib.Tracks{track},
)
@ -401,9 +409,11 @@ func TestRTSPServerAuthFail(t *testing.T) { @@ -401,9 +409,11 @@ func TestRTSPServerAuthFail(t *testing.T) {
require.NoError(t, err)
defer a.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
c := gortsplib.Client{}
@ -434,13 +444,15 @@ func TestRTSPServerPublisherOverride(t *testing.T) { @@ -434,13 +444,15 @@ func TestRTSPServerPublisherOverride(t *testing.T) {
require.Equal(t, true, ok)
defer p.close()
track, err := gortsplib.NewTrackH264(96,
[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
s1 := gortsplib.Client{}
err = s1.StartPublishing("rtsp://localhost:8554/teststream",
err := s1.StartPublishing("rtsp://localhost:8554/teststream",
gortsplib.Tracks{track})
require.NoError(t, err)
defer s1.Close()

31
internal/core/rtsp_source_test.go

@ -41,8 +41,14 @@ func TestRTSPSource(t *testing.T) { @@ -41,8 +41,14 @@ func TestRTSPSource(t *testing.T) {
"tls",
} {
t.Run(source, func(t *testing.T) {
track, _ := gortsplib.NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x05, 0x06}, nil)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
stream := gortsplib.NewServerStream(gortsplib.Tracks{track})
var authValidator *auth.Validator
s := gortsplib.Server{
@ -160,8 +166,14 @@ func TestRTSPSource(t *testing.T) { @@ -160,8 +166,14 @@ func TestRTSPSource(t *testing.T) {
}
func TestRTSPSourceNoPassword(t *testing.T) {
track, _ := gortsplib.NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x05, 0x06}, nil)
track := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{0x01, 0x02, 0x03, 0x04},
PPS: []byte{0x01, 0x02, 0x03, 0x04},
}
stream := gortsplib.NewServerStream(gortsplib.Tracks{track})
var authValidator *auth.Validator
done := make(chan struct{})
@ -218,8 +230,9 @@ func TestRTSPSourceNoPassword(t *testing.T) { @@ -218,8 +230,9 @@ func TestRTSPSourceNoPassword(t *testing.T) {
}
func TestRTSPSourceDynamicH264Params(t *testing.T) {
track, err := gortsplib.NewTrackH264(96, nil, nil, nil)
require.NoError(t, err)
track := &gortsplib.TrackH264{
PayloadType: 96,
}
stream := gortsplib.NewServerStream(gortsplib.Tracks{track})
defer stream.Close()
@ -244,7 +257,7 @@ func TestRTSPSourceDynamicH264Params(t *testing.T) { @@ -244,7 +257,7 @@ func TestRTSPSourceDynamicH264Params(t *testing.T) {
},
RTSPAddress: "127.0.0.1:8555",
}
err = s.Start()
err := s.Start()
require.NoError(t, err)
defer s.Wait()
defer s.Close()
@ -287,8 +300,8 @@ func TestRTSPSourceDynamicH264Params(t *testing.T) { @@ -287,8 +300,8 @@ func TestRTSPSourceDynamicH264Params(t *testing.T) {
h264Track, ok := tracks[0].(*gortsplib.TrackH264)
require.Equal(t, true, ok)
require.Equal(t, []byte{7, 1, 2, 3}, h264Track.SPS())
require.Equal(t, []byte{8}, h264Track.PPS())
require.Equal(t, []byte{7, 1, 2, 3}, h264Track.SafeSPS())
require.Equal(t, []byte{8}, h264Track.SafePPS())
}()
pkts, err = enc.Encode([][]byte{{7, 4, 5, 6}}, 0) // SPS
@ -316,7 +329,7 @@ func TestRTSPSourceDynamicH264Params(t *testing.T) { @@ -316,7 +329,7 @@ func TestRTSPSourceDynamicH264Params(t *testing.T) {
h264Track, ok := tracks[0].(*gortsplib.TrackH264)
require.Equal(t, true, ok)
require.Equal(t, []byte{7, 4, 5, 6}, h264Track.SPS())
require.Equal(t, []byte{8, 1}, h264Track.PPS())
require.Equal(t, []byte{7, 4, 5, 6}, h264Track.SafeSPS())
require.Equal(t, []byte{8, 1}, h264Track.SafePPS())
}()
}

10
internal/core/stream.go

@ -86,13 +86,13 @@ func (s *stream) updateH264TrackParameters(h264track *gortsplib.TrackH264, nalus @@ -86,13 +86,13 @@ func (s *stream) updateH264TrackParameters(h264track *gortsplib.TrackH264, nalus
switch typ {
case h264.NALUTypeSPS:
if !bytes.Equal(nalu, h264track.SPS()) {
h264track.SetSPS(append([]byte(nil), nalu...))
if !bytes.Equal(nalu, h264track.SafeSPS()) {
h264track.SafeSetSPS(append([]byte(nil), nalu...))
}
case h264.NALUTypePPS:
if !bytes.Equal(nalu, h264track.PPS()) {
h264track.SetPPS(append([]byte(nil), nalu...))
if !bytes.Equal(nalu, h264track.SafePPS()) {
h264track.SafeSetPPS(append([]byte(nil), nalu...))
}
}
}
@ -117,7 +117,7 @@ func (s *stream) remuxH264NALUs(h264track *gortsplib.TrackH264, data *data) { @@ -117,7 +117,7 @@ func (s *stream) remuxH264NALUs(h264track *gortsplib.TrackH264, data *data) {
case h264.NALUTypeIDR:
// add SPS and PPS before every IDR
filteredNALUs = append(filteredNALUs, h264track.SPS(), h264track.PPS())
filteredNALUs = append(filteredNALUs, h264track.SafeSPS(), h264track.SafePPS())
}
filteredNALUs = append(filteredNALUs, nalu)

11
internal/hls/client_audio_processor.go

@ -78,9 +78,14 @@ func (p *clientAudioProcessor) doProcess( @@ -78,9 +78,14 @@ func (p *clientAudioProcessor) doProcess(
if !p.trackInitialized {
p.trackInitialized = true
track, err := gortsplib.NewTrackAAC(96, pkt.Type, pkt.SampleRate, pkt.ChannelCount, nil, 13, 3, 3)
if err != nil {
return err
track := &gortsplib.TrackAAC{
PayloadType: 96,
Type: pkt.Type,
SampleRate: pkt.SampleRate,
ChannelCount: pkt.ChannelCount,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}
err = p.onTrack(track)

7
internal/hls/client_video_processor.go

@ -45,12 +45,11 @@ func newClientVideoProcessor( @@ -45,12 +45,11 @@ func newClientVideoProcessor(
}
func (p *clientVideoProcessor) run() error {
track, err := gortsplib.NewTrackH264(96, nil, nil, nil)
if err != nil {
return err
track := &gortsplib.TrackH264{
PayloadType: 96,
}
err = p.onTrack(track)
err := p.onTrack(track)
if err != nil {
return err
}

4
internal/hls/muxer_primary_playlist.go

@ -39,7 +39,7 @@ func (p *muxerPrimaryPlaylist) file() *MuxerFileResponse { @@ -39,7 +39,7 @@ func (p *muxerPrimaryPlaylist) file() *MuxerFileResponse {
var codecs []string
if p.videoTrack != nil {
sps := p.videoTrack.SPS()
sps := p.videoTrack.SafeSPS()
if len(sps) >= 4 {
codecs = append(codecs, "avc1."+hex.EncodeToString(sps[1:4]))
}
@ -47,7 +47,7 @@ func (p *muxerPrimaryPlaylist) file() *MuxerFileResponse { @@ -47,7 +47,7 @@ func (p *muxerPrimaryPlaylist) file() *MuxerFileResponse {
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter
if p.audioTrack != nil {
codecs = append(codecs, "mp4a.40."+strconv.FormatInt(int64(p.audioTrack.Type()), 10))
codecs = append(codecs, "mp4a.40."+strconv.FormatInt(int64(p.audioTrack.Type), 10))
}
switch {

57
internal/hls/muxer_test.go

@ -22,11 +22,21 @@ var testSPS = []byte{ @@ -22,11 +22,21 @@ var testSPS = []byte{
}
func TestMuxerVideoAudio(t *testing.T) {
videoTrack, err := gortsplib.NewTrackH264(96, testSPS, []byte{0x08}, nil)
require.NoError(t, err)
videoTrack := &gortsplib.TrackH264{
PayloadType: 96,
SPS: testSPS,
PPS: []byte{0x08},
}
audioTrack, err := gortsplib.NewTrackAAC(97, 2, 44100, 2, nil, 13, 3, 3)
require.NoError(t, err)
audioTrack := &gortsplib.TrackAAC{
PayloadType: 97,
Type: 2,
SampleRate: 44100,
ChannelCount: 2,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}
m, err := NewMuxer(MuxerVariantMPEGTS, 3, 1*time.Second, 0, 50*1024*1024, videoTrack, audioTrack)
require.NoError(t, err)
@ -183,8 +193,11 @@ func TestMuxerVideoAudio(t *testing.T) { @@ -183,8 +193,11 @@ func TestMuxerVideoAudio(t *testing.T) {
}
func TestMuxerVideoOnly(t *testing.T) {
videoTrack, err := gortsplib.NewTrackH264(96, testSPS, []byte{0x08}, nil)
require.NoError(t, err)
videoTrack := &gortsplib.TrackH264{
PayloadType: 96,
SPS: testSPS,
PPS: []byte{0x08},
}
m, err := NewMuxer(MuxerVariantMPEGTS, 3, 1*time.Second, 0, 50*1024*1024, videoTrack, nil)
require.NoError(t, err)
@ -266,8 +279,15 @@ func TestMuxerVideoOnly(t *testing.T) { @@ -266,8 +279,15 @@ func TestMuxerVideoOnly(t *testing.T) {
}
func TestMuxerAudioOnly(t *testing.T) {
audioTrack, err := gortsplib.NewTrackAAC(97, 2, 44100, 2, nil, 13, 3, 3)
require.NoError(t, err)
audioTrack := &gortsplib.TrackAAC{
PayloadType: 97,
Type: 2,
SampleRate: 44100,
ChannelCount: 2,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}
m, err := NewMuxer(MuxerVariantMPEGTS, 3, 1*time.Second, 0, 50*1024*1024, nil, audioTrack)
require.NoError(t, err)
@ -354,8 +374,11 @@ func TestMuxerAudioOnly(t *testing.T) { @@ -354,8 +374,11 @@ func TestMuxerAudioOnly(t *testing.T) {
}
func TestMuxerCloseBeforeFirstSegmentReader(t *testing.T) {
videoTrack, err := gortsplib.NewTrackH264(96, testSPS, []byte{0x08}, nil)
require.NoError(t, err)
videoTrack := &gortsplib.TrackH264{
PayloadType: 96,
SPS: testSPS,
PPS: []byte{0x08},
}
m, err := NewMuxer(MuxerVariantMPEGTS, 3, 1*time.Second, 0, 50*1024*1024, videoTrack, nil)
require.NoError(t, err)
@ -375,8 +398,11 @@ func TestMuxerCloseBeforeFirstSegmentReader(t *testing.T) { @@ -375,8 +398,11 @@ func TestMuxerCloseBeforeFirstSegmentReader(t *testing.T) {
}
func TestMuxerMaxSegmentSize(t *testing.T) {
videoTrack, err := gortsplib.NewTrackH264(96, testSPS, []byte{0x08}, nil)
require.NoError(t, err)
videoTrack := &gortsplib.TrackH264{
PayloadType: 96,
SPS: testSPS,
PPS: []byte{0x08},
}
m, err := NewMuxer(MuxerVariantMPEGTS, 3, 1*time.Second, 0, 0, videoTrack, nil)
require.NoError(t, err)
@ -390,8 +416,11 @@ func TestMuxerMaxSegmentSize(t *testing.T) { @@ -390,8 +416,11 @@ func TestMuxerMaxSegmentSize(t *testing.T) {
}
func TestMuxerDoubleRead(t *testing.T) {
videoTrack, err := gortsplib.NewTrackH264(96, testSPS, []byte{0x08}, nil)
require.NoError(t, err)
videoTrack := &gortsplib.TrackH264{
PayloadType: 96,
SPS: testSPS,
PPS: []byte{0x08},
}
m, err := NewMuxer(MuxerVariantMPEGTS, 3, 1*time.Second, 0, 50*1024*1024, videoTrack, nil)
require.NoError(t, err)

4
internal/hls/muxer_variant_fmp4.go

@ -104,8 +104,8 @@ func (v *muxerVariantFMP4) file(name string, msn string, part string, skip strin @@ -104,8 +104,8 @@ func (v *muxerVariantFMP4) file(name string, msn string, part string, skip strin
var sps []byte
var pps []byte
if v.videoTrack != nil {
sps = v.videoTrack.SPS()
pps = v.videoTrack.PPS()
sps = v.videoTrack.SafeSPS()
pps = v.videoTrack.SafePPS()
}
if v.initContent == nil ||

14
internal/hls/muxer_variant_fmp4_init.go

@ -51,8 +51,8 @@ func mp4InitGenerateVideoTrack(w *mp4.Writer, trackID int, videoTrack *gortsplib @@ -51,8 +51,8 @@ func mp4InitGenerateVideoTrack(w *mp4.Writer, trackID int, videoTrack *gortsplib
return err
}
sps := videoTrack.SPS()
pps := videoTrack.PPS()
sps := videoTrack.SafeSPS()
pps := videoTrack.SafePPS()
var spsp h264.SPS
err = spsp.Unmarshal(sps)
@ -389,7 +389,7 @@ func mp4InitGenerateAudioTrack(w *mp4.Writer, trackID int, audioTrack *gortsplib @@ -389,7 +389,7 @@ func mp4InitGenerateAudioTrack(w *mp4.Writer, trackID int, audioTrack *gortsplib
},
DataReferenceIndex: 1,
},
ChannelCount: uint16(audioTrack.ChannelCount()),
ChannelCount: uint16(audioTrack.ChannelCount),
SampleSize: 16,
SampleRate: uint32(audioTrack.ClockRate() * 65536),
})
@ -398,10 +398,10 @@ func mp4InitGenerateAudioTrack(w *mp4.Writer, trackID int, audioTrack *gortsplib @@ -398,10 +398,10 @@ func mp4InitGenerateAudioTrack(w *mp4.Writer, trackID int, audioTrack *gortsplib
}
c := aac.MPEG4AudioConfig{
Type: aac.MPEG4AudioType(audioTrack.Type()),
SampleRate: audioTrack.ClockRate(),
ChannelCount: audioTrack.ChannelCount(),
AOTSpecificConfig: audioTrack.AOTSpecificConfig(),
Type: aac.MPEG4AudioType(audioTrack.Type),
SampleRate: audioTrack.SampleRate,
ChannelCount: audioTrack.ChannelCount,
AOTSpecificConfig: audioTrack.AOTSpecificConfig,
}
conf, _ := c.Encode()

4
internal/hls/muxer_variant_fmp4_segmenter.go

@ -162,7 +162,7 @@ func (m *muxerVariantFMP4Segmenter) writeH264Entry(sample *fmp4VideoSample) erro @@ -162,7 +162,7 @@ func (m *muxerVariantFMP4Segmenter) writeH264Entry(sample *fmp4VideoSample) erro
m.videoFirstIDRReceived = true
m.videoDTSExtractor = h264.NewDTSExtractor()
m.videoSPS = append([]byte(nil), m.videoTrack.SPS()...)
m.videoSPS = append([]byte(nil), m.videoTrack.SafeSPS()...)
var err error
sample.dts, err = m.videoDTSExtractor.Extract(sample.nalus, sample.pts)
@ -221,7 +221,7 @@ func (m *muxerVariantFMP4Segmenter) writeH264Entry(sample *fmp4VideoSample) erro @@ -221,7 +221,7 @@ func (m *muxerVariantFMP4Segmenter) writeH264Entry(sample *fmp4VideoSample) erro
// switch segment
if sample.next.idrPresent {
sps := m.videoTrack.SPS()
sps := m.videoTrack.SafeSPS()
spsChanged := !bytes.Equal(m.videoSPS, sps)
if (sample.next.dts-m.currentSegment.startDTS) >= m.segmentDuration ||

6
internal/hls/muxer_variant_mpegts_segment.go

@ -151,9 +151,9 @@ func (t *muxerVariantMPEGTSSegment) writeAAC( @@ -151,9 +151,9 @@ func (t *muxerVariantMPEGTSSegment) writeAAC(
for i, au := range aus {
pkts[i] = &aac.ADTSPacket{
Type: t.audioTrack.Type(),
SampleRate: t.audioTrack.ClockRate(),
ChannelCount: t.audioTrack.ChannelCount(),
Type: t.audioTrack.Type,
SampleRate: t.audioTrack.SampleRate,
ChannelCount: t.audioTrack.ChannelCount,
AU: au,
}
}

32
internal/rtmp/conn.go

@ -89,7 +89,11 @@ func trackFromH264DecoderConfig(data []byte) (*gortsplib.TrackH264, error) { @@ -89,7 +89,11 @@ func trackFromH264DecoderConfig(data []byte) (*gortsplib.TrackH264, error) {
return nil, err
}
return gortsplib.NewTrackH264(96, codec.SPS[0], codec.PPS[0], nil)
return &gortsplib.TrackH264{
PayloadType: 96,
SPS: codec.SPS[0],
PPS: codec.PPS[0],
}, nil
}
func trackFromAACDecoderConfig(data []byte) (*gortsplib.TrackAAC, error) {
@ -99,8 +103,16 @@ func trackFromAACDecoderConfig(data []byte) (*gortsplib.TrackAAC, error) { @@ -99,8 +103,16 @@ func trackFromAACDecoderConfig(data []byte) (*gortsplib.TrackAAC, error) {
return nil, err
}
return gortsplib.NewTrackAAC(96, int(mpegConf.Type), mpegConf.SampleRate,
mpegConf.ChannelCount, mpegConf.AOTSpecificConfig, 13, 3, 3)
return &gortsplib.TrackAAC{
PayloadType: 97,
Type: int(mpegConf.Type),
SampleRate: mpegConf.SampleRate,
ChannelCount: mpegConf.ChannelCount,
AOTSpecificConfig: mpegConf.AOTSpecificConfig,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}, nil
}
var errEmptyMetadata = errors.New("metadata is empty")
@ -359,13 +371,13 @@ func (c *Conn) WriteTracks(videoTrack *gortsplib.TrackH264, audioTrack *gortspli @@ -359,13 +371,13 @@ func (c *Conn) WriteTracks(videoTrack *gortsplib.TrackH264, audioTrack *gortspli
// write decoder config only if SPS and PPS are available.
// if they're not available yet, they're sent later as H264 NALUs.
if videoTrack != nil && videoTrack.SPS() != nil && videoTrack.PPS() != nil {
if videoTrack != nil && videoTrack.SafeSPS() != nil && videoTrack.SafePPS() != nil {
codec := nh264.Codec{
SPS: map[int][]byte{
0: videoTrack.SPS(),
0: videoTrack.SafeSPS(),
},
PPS: map[int][]byte{
0: videoTrack.PPS(),
0: videoTrack.SafePPS(),
},
}
b := make([]byte, 128)
@ -384,10 +396,10 @@ func (c *Conn) WriteTracks(videoTrack *gortsplib.TrackH264, audioTrack *gortspli @@ -384,10 +396,10 @@ func (c *Conn) WriteTracks(videoTrack *gortsplib.TrackH264, audioTrack *gortspli
if audioTrack != nil {
enc, err := aac.MPEG4AudioConfig{
Type: aac.MPEG4AudioType(audioTrack.Type()),
SampleRate: audioTrack.ClockRate(),
ChannelCount: audioTrack.ChannelCount(),
AOTSpecificConfig: audioTrack.AOTSpecificConfig(),
Type: aac.MPEG4AudioType(audioTrack.Type),
SampleRate: audioTrack.SampleRate,
ChannelCount: audioTrack.ChannelCount,
AOTSpecificConfig: audioTrack.AOTSpecificConfig,
}.Encode()
if err != nil {
return err

89
internal/rtmp/conn_test.go

@ -85,31 +85,55 @@ func TestReadTracks(t *testing.T) { @@ -85,31 +85,55 @@ func TestReadTracks(t *testing.T) {
switch ca {
case "standard":
videoTrack2, err := gortsplib.NewTrackH264(96, sps, pps, nil)
require.NoError(t, err)
require.Equal(t, videoTrack2, videoTrack)
audioTrack2, err := gortsplib.NewTrackAAC(96, 2, 44100, 2, nil, 13, 3, 3)
require.NoError(t, err)
require.Equal(t, audioTrack2, audioTrack)
require.Equal(t, &gortsplib.TrackH264{
PayloadType: 96,
SPS: sps,
PPS: pps,
}, videoTrack)
require.Equal(t, &gortsplib.TrackAAC{
PayloadType: 97,
Type: 2,
SampleRate: 44100,
ChannelCount: 2,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}, audioTrack)
case "metadata without codec id":
videoTrack2, err := gortsplib.NewTrackH264(96, sps, pps, nil)
require.NoError(t, err)
require.Equal(t, videoTrack2, videoTrack)
audioTrack2, err := gortsplib.NewTrackAAC(96, 2, 44100, 2, nil, 13, 3, 3)
require.NoError(t, err)
require.Equal(t, audioTrack2, audioTrack)
require.Equal(t, &gortsplib.TrackH264{
PayloadType: 96,
SPS: sps,
PPS: pps,
}, videoTrack)
require.Equal(t, &gortsplib.TrackAAC{
PayloadType: 97,
Type: 2,
SampleRate: 44100,
ChannelCount: 2,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}, audioTrack)
case "missing metadata":
videoTrack2, err := gortsplib.NewTrackH264(96, sps, pps, nil)
require.NoError(t, err)
require.Equal(t, videoTrack2, videoTrack)
audioTrack2, err := gortsplib.NewTrackAAC(96, 2, 44100, 2, nil, 13, 3, 3)
require.NoError(t, err)
require.Equal(t, audioTrack2, audioTrack)
require.Equal(t, &gortsplib.TrackH264{
PayloadType: 96,
SPS: sps,
PPS: pps,
}, videoTrack)
require.Equal(t, &gortsplib.TrackAAC{
PayloadType: 97,
Type: 2,
SampleRate: 44100,
ChannelCount: 2,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}, audioTrack)
}
close(done)
@ -492,20 +516,27 @@ func TestWriteTracks(t *testing.T) { @@ -492,20 +516,27 @@ func TestWriteTracks(t *testing.T) {
err = rconn.ServerHandshake()
require.NoError(t, err)
videoTrack, err := gortsplib.NewTrackH264(96,
[]byte{
videoTrack := &gortsplib.TrackH264{
PayloadType: 96,
SPS: []byte{
0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0,
0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
0x00, 0x03, 0x00, 0x3d, 0x08,
},
[]byte{
PPS: []byte{
0x68, 0xee, 0x3c, 0x80,
},
nil)
require.NoError(t, err)
audioTrack, err := gortsplib.NewTrackAAC(96, 2, 44100, 2, nil, 13, 3, 3)
require.NoError(t, err)
}
audioTrack := &gortsplib.TrackAAC{
PayloadType: 97,
Type: 2,
SampleRate: 44100,
ChannelCount: 2,
SizeLength: 13,
IndexLength: 3,
IndexDeltaLength: 3,
}
err = rconn.WriteTracks(videoTrack, audioTrack)
require.NoError(t, err)

Loading…
Cancel
Save