From 9f4fea8a013afe4da70da4be603ecd21c21a83db Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Thu, 23 Jun 2022 13:13:36 +0200 Subject: [PATCH] change track initialization method --- client_publish_test.go | 49 +++-- client_read_test.go | 144 +++++++++++---- client_test.go | 21 ++- examples/client-publish-aac/main.go | 11 +- examples/client-publish-h264/main.go | 5 +- examples/client-publish-options/main.go | 5 +- examples/client-publish-opus/main.go | 6 +- examples/client-publish-pause/main.go | 5 +- examples/client-publish-pcmu/main.go | 2 +- examples/client-read-aac/main.go | 8 +- .../client-read-h264-convert-to-jpeg/main.go | 10 +- .../client-read-h264-save-to-disk/main.go | 2 +- examples/client-read-h264/main.go | 10 +- server_publish_test.go | 85 ++++++--- server_read_test.go | 142 ++++++++++----- server_test.go | 50 +++-- track_aac.go | 171 ++++++------------ track_aac_test.go | 41 ++--- track_generic.go | 61 +++---- track_generic_test.go | 49 ++--- track_h264.go | 84 ++++----- track_h264_test.go | 42 +++-- track_h265.go | 87 ++++----- track_h265_test.go | 37 +++- track_jpeg.go | 5 - track_jpeg_test.go | 9 +- track_mpegaudio.go | 5 - track_mpegaudio_test.go | 6 +- track_mpegvideo.go | 5 - track_mpegvideo_test.go | 6 +- track_opus.go | 43 ++--- track_opus_test.go | 19 +- track_pcma.go | 5 - track_pcma_test.go | 6 +- track_pcmu.go | 5 - track_pcmu_test.go | 6 +- track_test.go | 130 +++++++------ track_vp9.go | 63 ++----- track_vp9_test.go | 25 ++- tracks_test.go | 6 +- 40 files changed, 765 insertions(+), 706 deletions(-) diff --git a/client_publish_test.go b/client_publish_test.go index 530564a6..7ce88091 100644 --- a/client_publish_test.go +++ b/client_publish_test.go @@ -237,8 +237,11 @@ func TestClientPublishSerial(t *testing.T) { }, } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } err = c.StartPublishing(scheme+"://localhost:8554/teststream", Tracks{track}) @@ -391,8 +394,11 @@ func TestClientPublishParallel(t *testing.T) { }(), } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } writerDone := make(chan struct{}) defer func() { <-writerDone }() @@ -554,8 +560,11 @@ func TestClientPublishPauseSerial(t *testing.T) { }(), } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } err = c.StartPublishing("rtsp://localhost:8554/teststream", Tracks{track}) @@ -690,8 +699,11 @@ func TestClientPublishPauseParallel(t *testing.T) { }(), } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } err = c.StartPublishing("rtsp://localhost:8554/teststream", Tracks{track}) @@ -835,8 +847,11 @@ func TestClientPublishAutomaticProtocol(t *testing.T) { require.NoError(t, err) }() - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } c := Client{} @@ -975,8 +990,11 @@ func TestClientPublishRTCPReport(t *testing.T) { udpSenderReportPeriod: 1 * time.Second, } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } err = c.StartPublishing("rtsp://localhost:8554/teststream", Tracks{track}) @@ -1117,8 +1135,11 @@ func TestClientPublishIgnoreTCPRTPPackets(t *testing.T) { }, } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } err = c.StartPublishing("rtsp://localhost:8554/teststream", Tracks{track}) diff --git a/client_read_test.go b/client_read_test.go index ec4e2552..93966c9e 100644 --- a/client_read_test.go +++ b/client_read_test.go @@ -22,14 +22,33 @@ import ( ) func TestClientReadTracks(t *testing.T) { - track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track1 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } - track2, err := NewTrackAAC(96, 2, 44100, 2, nil, 13, 3, 3) - require.NoError(t, err) + track2 := &TrackAAC{ + PayloadType: 96, + Type: 2, + SampleRate: 44100, + ChannelCount: 2, + AOTSpecificConfig: nil, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, + } - track3, err := NewTrackAAC(96, 2, 96000, 2, nil, 13, 3, 3) - require.NoError(t, err) + track3 := &TrackAAC{ + PayloadType: 96, + Type: 2, + SampleRate: 96000, + ChannelCount: 2, + AOTSpecificConfig: nil, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, + } l, err := net.Listen("tcp", "localhost:8554") require.NoError(t, err) @@ -203,8 +222,11 @@ func TestClientRead(t *testing.T) { require.Equal(t, base.Describe, req.Method) require.Equal(t, mustParseURL(scheme+"://"+listenIP+":8554/test/stream?param=value"), req.URL) - track, err := NewTrackGeneric("application", []string{"97"}, "97 private/90000", "") - require.NoError(t, err) + track := &TrackGeneric{ + Media: "application", + Formats: []string{"97"}, + RTPMap: "97 private/90000", + } tracks := Tracks{track} tracks.setControls() @@ -464,11 +486,17 @@ func TestClientReadPartial(t *testing.T) { require.Equal(t, base.Describe, req.Method) require.Equal(t, mustParseURL("rtsp://"+listenIP+":8554/teststream"), req.URL) - track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track1 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } - track2, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track2 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track1, track2} tracks.setControls() @@ -617,8 +645,11 @@ func TestClientReadContentBase(t *testing.T) { require.Equal(t, base.Describe, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -756,8 +787,11 @@ func TestClientReadAnyPort(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -915,8 +949,11 @@ func TestClientReadAutomaticProtocol(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1053,8 +1090,11 @@ func TestClientReadAutomaticProtocol(t *testing.T) { err = v.ValidateRequest(req) require.NoError(t, err) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1285,8 +1325,11 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) { require.Equal(t, base.Describe, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track1 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track1} tracks.setControls() @@ -1499,8 +1542,11 @@ func TestClientReadRedirect(t *testing.T) { require.Equal(t, base.Describe, req.Method) } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1660,8 +1706,11 @@ func TestClientReadPause(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1838,9 +1887,11 @@ func TestClientReadRTCPReport(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, - []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -2022,8 +2073,11 @@ func TestClientReadErrorTimeout(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -2176,8 +2230,11 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -2309,8 +2366,11 @@ func TestClientReadSeek(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -2485,8 +2545,11 @@ func TestClientReadKeepaliveFromSession(t *testing.T) { require.NoError(t, err) require.Equal(t, base.Describe, req.Method) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -2616,8 +2679,11 @@ func TestClientReadDifferentSource(t *testing.T) { require.Equal(t, base.Describe, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/test/stream?param=value"), req.URL) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() diff --git a/client_test.go b/client_test.go index f1d80658..cf51288b 100644 --- a/client_test.go +++ b/client_test.go @@ -118,8 +118,11 @@ func TestClientSession(t *testing.T) { require.Equal(t, base.HeaderValue{"123456"}, req.Header["Session"]) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -201,8 +204,11 @@ func TestClientAuth(t *testing.T) { err = v.ValidateRequest(req) require.NoError(t, err) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -266,8 +272,11 @@ func TestClientDescribeCharset(t *testing.T) { require.Equal(t, base.Describe, req.Method) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL) - track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track1 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } byts, _ = base.Response{ StatusCode: base.StatusOK, diff --git a/examples/client-publish-aac/main.go b/examples/client-publish-aac/main.go index 707d9e9a..f0d8fbf7 100644 --- a/examples/client-publish-aac/main.go +++ b/examples/client-publish-aac/main.go @@ -34,9 +34,14 @@ func main() { log.Println("stream connected") // create an AAC track - track, err := gortsplib.NewTrackAAC(96, 2, 48000, 2, nil, 13, 3, 3) - if err != nil { - panic(err) + track := &gortsplib.TrackAAC{ + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, } // connect to the server and start publishing the track diff --git a/examples/client-publish-h264/main.go b/examples/client-publish-h264/main.go index d6d8f22c..cad65398 100644 --- a/examples/client-publish-h264/main.go +++ b/examples/client-publish-h264/main.go @@ -35,9 +35,8 @@ func main() { log.Println("stream connected") // create an H264 track - track, err := gortsplib.NewTrackH264(96, nil, nil, nil) - if err != nil { - panic(err) + track := &gortsplib.TrackH264{ + PayloadType: 96, } // connect to the server and start publishing the track diff --git a/examples/client-publish-options/main.go b/examples/client-publish-options/main.go index ba5712b3..86278038 100644 --- a/examples/client-publish-options/main.go +++ b/examples/client-publish-options/main.go @@ -36,9 +36,8 @@ func main() { log.Println("stream connected") // create an H264 track - track, err := gortsplib.NewTrackH264(96, nil, nil, nil) - if err != nil { - panic(err) + track := &gortsplib.TrackH264{ + PayloadType: 96, } // Client allows to set additional client options diff --git a/examples/client-publish-opus/main.go b/examples/client-publish-opus/main.go index 23bf6620..6ff99028 100644 --- a/examples/client-publish-opus/main.go +++ b/examples/client-publish-opus/main.go @@ -34,7 +34,11 @@ func main() { log.Println("stream connected") // create an Opus track - track := gortsplib.NewTrackOpus(96, 48000, 2) + track := &gortsplib.TrackOpus{ + PayloadType: 96, + SampleRate: 48000, + ChannelCount: 2, + } c := gortsplib.Client{} diff --git a/examples/client-publish-pause/main.go b/examples/client-publish-pause/main.go index 8051523b..34328d40 100644 --- a/examples/client-publish-pause/main.go +++ b/examples/client-publish-pause/main.go @@ -37,9 +37,8 @@ func main() { log.Println("stream connected") // create an H264 track - track, err := gortsplib.NewTrackH264(96, nil, nil, nil) - if err != nil { - panic(err) + track := &gortsplib.TrackH264{ + PayloadType: 96, } // connect to the server and start publishing the track diff --git a/examples/client-publish-pcmu/main.go b/examples/client-publish-pcmu/main.go index c1c734bc..10176243 100644 --- a/examples/client-publish-pcmu/main.go +++ b/examples/client-publish-pcmu/main.go @@ -34,7 +34,7 @@ func main() { log.Println("stream connected") // create a PCMU track - track := gortsplib.NewTrackPCMU() + track := &gortsplib.TrackPCMU{} c := gortsplib.Client{} diff --git a/examples/client-read-aac/main.go b/examples/client-read-aac/main.go index 41a418b9..47307de8 100644 --- a/examples/client-read-aac/main.go +++ b/examples/client-read-aac/main.go @@ -50,10 +50,10 @@ func main() { // setup decoder dec := &rtpaac.Decoder{ - SampleRate: aacTrack.ClockRate(), - SizeLength: aacTrack.SizeLength(), - IndexLength: aacTrack.IndexLength(), - IndexDeltaLength: aacTrack.IndexDeltaLength(), + SampleRate: aacTrack.SampleRate, + SizeLength: aacTrack.SizeLength, + IndexLength: aacTrack.IndexLength, + IndexDeltaLength: aacTrack.IndexDeltaLength, } dec.Init() diff --git a/examples/client-read-h264-convert-to-jpeg/main.go b/examples/client-read-h264-convert-to-jpeg/main.go index 3d5204ef..b1a7fe35 100644 --- a/examples/client-read-h264-convert-to-jpeg/main.go +++ b/examples/client-read-h264-convert-to-jpeg/main.go @@ -81,11 +81,13 @@ func main() { defer h264dec.close() // if present, send SPS and PPS from the SDP to the decoder - if h264track.SPS() != nil { - h264dec.decode(h264track.SPS()) + sps := h264track.SafeSPS() + if sps != nil { + h264dec.decode(sps) } - if h264track.PPS() != nil { - h264dec.decode(h264track.PPS()) + pps := h264track.SafePPS() + if pps != nil { + h264dec.decode(pps) } // called when a RTP packet arrives diff --git a/examples/client-read-h264-save-to-disk/main.go b/examples/client-read-h264-save-to-disk/main.go index a02df084..93d7277c 100644 --- a/examples/client-read-h264-save-to-disk/main.go +++ b/examples/client-read-h264-save-to-disk/main.go @@ -46,7 +46,7 @@ func main() { } // setup H264->MPEGTS encoder - enc, err := newMPEGTSEncoder(h264track.SPS(), h264track.PPS()) + enc, err := newMPEGTSEncoder(h264track.SafeSPS(), h264track.SafePPS()) if err != nil { panic(err) } diff --git a/examples/client-read-h264/main.go b/examples/client-read-h264/main.go index c7804c99..2326b0b5 100644 --- a/examples/client-read-h264/main.go +++ b/examples/client-read-h264/main.go @@ -58,11 +58,13 @@ func main() { defer h264dec.close() // if present, send SPS and PPS from the SDP to the decoder - if h264track.SPS() != nil { - h264dec.decode(h264track.SPS()) + sps := h264track.SafeSPS() + if sps != nil { + h264dec.decode(sps) } - if h264track.PPS() != nil { - h264dec.decode(h264track.PPS()) + pps := h264track.SafePPS() + if pps != nil { + h264dec.decode(pps) } // called when a RTP packet arrives diff --git a/server_publish_test.go b/server_publish_test.go index f3d38045..4417a4cd 100644 --- a/server_publish_test.go +++ b/server_publish_test.go @@ -25,8 +25,11 @@ func invalidURLAnnounceReq(t *testing.T, control string) base.Request { "Content-Type": base.HeaderValue{"application/sdp"}, }, Body: func() []byte { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } track.SetControl(control) sout := &psdp.SessionDescription{ @@ -227,9 +230,11 @@ func TestServerPublishSetupPath(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) - + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } track.SetControl(ca.control) sout := &psdp.SessionDescription{ @@ -320,8 +325,11 @@ func TestServerPublishErrorSetupDifferentPaths(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -397,8 +405,11 @@ func TestServerPublishErrorSetupTrackTwice(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -495,11 +506,17 @@ func TestServerPublishErrorRecordPartialTracks(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track1 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } - track2, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track2 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track1, track2} tracks.setControls() @@ -646,8 +663,11 @@ func TestServerPublish(t *testing.T) { <-connOpened - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -847,8 +867,11 @@ func TestServerPublishErrorInvalidProtocol(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -950,8 +973,11 @@ func TestServerPublishRTCPReport(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1124,8 +1150,11 @@ func TestServerPublishTimeout(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1250,8 +1279,11 @@ func TestServerPublishWithoutTeardown(t *testing.T) { require.NoError(t, err) br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -1368,8 +1400,11 @@ func TestServerPublishUDPChangeConn(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() diff --git a/server_read_test.go b/server_read_test.go index 22362131..badc09bc 100644 --- a/server_read_test.go +++ b/server_read_test.go @@ -92,8 +92,11 @@ func TestServerReadSetupPath(t *testing.T) { }, } { t.Run(ca.name, func(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track, track, track, track, track}) defer stream.Close() @@ -111,7 +114,7 @@ func TestServerReadSetupPath(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -156,8 +159,11 @@ func TestServerReadSetupErrors(t *testing.T) { t.Run(ca, func(t *testing.T) { connClosed := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) if ca == "closed stream" { @@ -190,7 +196,7 @@ func TestServerReadSetupErrors(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -288,8 +294,11 @@ func TestServerRead(t *testing.T) { sessionClosed := make(chan struct{}) framesReceived := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -372,7 +381,7 @@ func TestServerRead(t *testing.T) { s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}} } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -628,8 +637,11 @@ func TestServerRead(t *testing.T) { } func TestServerReadRTCPReport(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -653,7 +665,7 @@ func TestServerReadRTCPReport(t *testing.T) { UDPRTCPAddress: "127.0.0.1:8001", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -738,8 +750,11 @@ func TestServerReadRTCPReport(t *testing.T) { } func TestServerReadVLCMulticast(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -760,7 +775,7 @@ func TestServerReadVLCMulticast(t *testing.T) { MulticastRTCPPort: 8001, } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -790,8 +805,11 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) { writerDone := make(chan struct{}) writerTerminate := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -836,7 +854,7 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) { }, } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -888,8 +906,11 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) { } func TestServerReadPlayPlay(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -912,7 +933,7 @@ func TestServerReadPlayPlay(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -975,8 +996,11 @@ func TestServerReadPlayPausePlay(t *testing.T) { writerDone := make(chan struct{}) writerTerminate := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -1025,7 +1049,7 @@ func TestServerReadPlayPausePlay(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1098,8 +1122,11 @@ func TestServerReadPlayPausePause(t *testing.T) { writerDone := make(chan struct{}) writerTerminate := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -1145,7 +1172,7 @@ func TestServerReadPlayPausePause(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1231,8 +1258,11 @@ func TestServerReadTimeout(t *testing.T) { t.Run(transport, func(t *testing.T) { sessionClosed := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -1274,7 +1304,7 @@ func TestServerReadTimeout(t *testing.T) { s.MulticastRTCPPort = 8001 } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1343,8 +1373,11 @@ func TestServerReadWithoutTeardown(t *testing.T) { connClosed := make(chan struct{}) sessionClosed := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -1383,7 +1416,7 @@ func TestServerReadWithoutTeardown(t *testing.T) { s.UDPRTCPAddress = "127.0.0.1:8001" } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1446,8 +1479,11 @@ func TestServerReadWithoutTeardown(t *testing.T) { } func TestServerReadUDPChangeConn(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -1475,7 +1511,7 @@ func TestServerReadUDPChangeConn(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1549,11 +1585,17 @@ func TestServerReadUDPChangeConn(t *testing.T) { } func TestServerReadPartialTracks(t *testing.T) { - track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track1 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } - track2, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track2 := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track1, track2}) defer stream.Close() @@ -1580,7 +1622,7 @@ func TestServerReadPartialTracks(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1725,8 +1767,11 @@ func TestServerReadAdditionalInfos(t *testing.T) { return &ri, ssrcs } - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track, track}) defer stream.Close() @@ -1747,7 +1792,7 @@ func TestServerReadAdditionalInfos(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -1836,8 +1881,11 @@ func TestServerReadAdditionalInfos(t *testing.T) { } func TestServerReadErrorUDPSamePorts(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -1860,7 +1908,7 @@ func TestServerReadErrorUDPSamePorts(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() diff --git a/server_test.go b/server_test.go index 21eb5d57..b67946e9 100644 --- a/server_test.go +++ b/server_test.go @@ -351,8 +351,11 @@ func TestServerErrorInvalidMethod(t *testing.T) { } func TestServerErrorTCPTwoConnOneSession(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -378,7 +381,7 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -454,8 +457,11 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) { } func TestServerErrorTCPOneConnTwoSessions(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -481,7 +487,7 @@ func TestServerErrorTCPOneConnTwoSessions(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -727,8 +733,11 @@ func TestServerSessionAutoClose(t *testing.T) { t.Run(ca, func(t *testing.T) { sessionClosed := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -753,7 +762,7 @@ func TestServerSessionAutoClose(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -802,8 +811,11 @@ func TestServerErrorInvalidPath(t *testing.T) { t.Run(string(method), func(t *testing.T) { connClosed := make(chan struct{}) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } stream := NewServerStream(Tracks{track}) defer stream.Close() @@ -833,7 +845,7 @@ func TestServerErrorInvalidPath(t *testing.T) { RTSPAddress: "localhost:8554", } - err = s.Start() + err := s.Start() require.NoError(t, err) defer s.Close() @@ -845,8 +857,11 @@ func TestServerErrorInvalidPath(t *testing.T) { sxID := "" if method == base.Record { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } tracks := Tracks{track} tracks.setControls() @@ -961,8 +976,11 @@ func TestServerAuth(t *testing.T) { defer conn.Close() br := bufio.NewReader(conn) - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02, 0x03, 0x04}, + PPS: []byte{0x01, 0x02, 0x03, 0x04}, + } req := base.Request{ Method: base.Announce, diff --git a/track_aac.go b/track_aac.go index a572ddb5..5dabb5d2 100644 --- a/track_aac.go +++ b/track_aac.go @@ -13,49 +13,16 @@ import ( // TrackAAC is an AAC track. type TrackAAC struct { + PayloadType uint8 + Type int + SampleRate int + ChannelCount int + AOTSpecificConfig []byte + SizeLength int + IndexLength int + IndexDeltaLength int + trackBase - payloadType uint8 - typ int - sampleRate int - channelCount int - aotSpecificConfig []byte - mpegConf []byte - sizeLength int - indexLength int - indexDeltaLength int -} - -// NewTrackAAC allocates a TrackAAC. -func NewTrackAAC(payloadType uint8, - typ int, - sampleRate int, - channelCount int, - aotSpecificConfig []byte, - sizeLength int, - indexLength int, - indexDeltaLength int, -) (*TrackAAC, error) { - mpegConf, err := aac.MPEG4AudioConfig{ - Type: aac.MPEG4AudioType(typ), - SampleRate: sampleRate, - ChannelCount: channelCount, - AOTSpecificConfig: aotSpecificConfig, - }.Encode() - if err != nil { - return nil, fmt.Errorf("invalid configuration: %s", err) - } - - return &TrackAAC{ - payloadType: payloadType, - typ: typ, - sampleRate: sampleRate, - channelCount: channelCount, - aotSpecificConfig: aotSpecificConfig, - mpegConf: mpegConf, - sizeLength: sizeLength, - indexLength: indexLength, - indexDeltaLength: indexDeltaLength, - }, nil } func newTrackAACFromMediaDescription( @@ -73,13 +40,15 @@ func newTrackAACFromMediaDescription( return nil, fmt.Errorf("invalid fmtp (%v)", v) } - track := &TrackAAC{ + t := &TrackAAC{ + PayloadType: payloadType, trackBase: trackBase{ control: control, }, - payloadType: payloadType, } + configFound := false + for _, kv := range strings.Split(tmp[1], ";") { kv = strings.Trim(kv, " ") @@ -99,108 +68,84 @@ func newTrackAACFromMediaDescription( return nil, fmt.Errorf("invalid AAC config (%v)", tmp[1]) } - var mpegConf aac.MPEG4AudioConfig - err = mpegConf.Decode(enc) + var MPEGConf aac.MPEG4AudioConfig + err = MPEGConf.Decode(enc) if err != nil { return nil, fmt.Errorf("invalid AAC config (%v)", tmp[1]) } - // re-encode the conf to normalize it - enc, _ = mpegConf.Encode() - - track.typ = int(mpegConf.Type) - track.sampleRate = mpegConf.SampleRate - track.channelCount = mpegConf.ChannelCount - track.aotSpecificConfig = mpegConf.AOTSpecificConfig - track.mpegConf = enc + t.Type = int(MPEGConf.Type) + t.SampleRate = MPEGConf.SampleRate + t.ChannelCount = MPEGConf.ChannelCount + t.AOTSpecificConfig = MPEGConf.AOTSpecificConfig + configFound = true case "sizelength": val, err := strconv.ParseUint(tmp[1], 10, 64) if err != nil { - return nil, fmt.Errorf("invalid AAC sizeLength (%v)", tmp[1]) + return nil, fmt.Errorf("invalid AAC SizeLength (%v)", tmp[1]) } - track.sizeLength = int(val) + t.SizeLength = int(val) case "indexlength": val, err := strconv.ParseUint(tmp[1], 10, 64) if err != nil { - return nil, fmt.Errorf("invalid AAC indexLength (%v)", tmp[1]) + return nil, fmt.Errorf("invalid AAC IndexLength (%v)", tmp[1]) } - track.indexLength = int(val) + t.IndexLength = int(val) case "indexdeltalength": val, err := strconv.ParseUint(tmp[1], 10, 64) if err != nil { - return nil, fmt.Errorf("invalid AAC indexDeltaLength (%v)", tmp[1]) + return nil, fmt.Errorf("invalid AAC IndexDeltaLength (%v)", tmp[1]) } - track.indexDeltaLength = int(val) + t.IndexDeltaLength = int(val) } } - if len(track.mpegConf) == 0 { + if !configFound { return nil, fmt.Errorf("config is missing (%v)", v) } - if track.sizeLength == 0 { + if t.SizeLength == 0 { return nil, fmt.Errorf("sizelength is missing (%v)", v) } - return track, nil + return t, nil } // ClockRate returns the track clock rate. func (t *TrackAAC) ClockRate() int { - return t.sampleRate -} - -// Type returns the track MPEG4-audio type. -func (t *TrackAAC) Type() int { - return t.typ -} - -// ChannelCount returns the track channel count. -func (t *TrackAAC) ChannelCount() int { - return t.channelCount -} - -// AOTSpecificConfig returns the track AOT specific config. -func (t *TrackAAC) AOTSpecificConfig() []byte { - return t.aotSpecificConfig -} - -// SizeLength returns the track sizeLength. -func (t *TrackAAC) SizeLength() int { - return t.sizeLength -} - -// IndexLength returns the track indexLength. -func (t *TrackAAC) IndexLength() int { - return t.indexLength -} - -// IndexDeltaLength returns the track indexDeltaLength. -func (t *TrackAAC) IndexDeltaLength() int { - return t.indexDeltaLength + return t.SampleRate } func (t *TrackAAC) clone() Track { return &TrackAAC{ + PayloadType: t.PayloadType, + Type: t.Type, + SampleRate: t.SampleRate, + ChannelCount: t.ChannelCount, + AOTSpecificConfig: t.AOTSpecificConfig, + SizeLength: t.SizeLength, + IndexLength: t.IndexLength, + IndexDeltaLength: t.IndexDeltaLength, trackBase: t.trackBase, - payloadType: t.payloadType, - typ: t.typ, - sampleRate: t.sampleRate, - channelCount: t.channelCount, - aotSpecificConfig: t.aotSpecificConfig, - mpegConf: t.mpegConf, - sizeLength: t.sizeLength, - indexLength: t.indexLength, - indexDeltaLength: t.indexDeltaLength, } } // MediaDescription returns the track media description in SDP format. func (t *TrackAAC) MediaDescription() *psdp.MediaDescription { - typ := strconv.FormatInt(int64(t.payloadType), 10) + mpegConf, err := aac.MPEG4AudioConfig{ + Type: aac.MPEG4AudioType(t.Type), + SampleRate: t.SampleRate, + ChannelCount: t.ChannelCount, + AOTSpecificConfig: t.AOTSpecificConfig, + }.Encode() + if err != nil { + return nil + } + + typ := strconv.FormatInt(int64(t.PayloadType), 10) return &psdp.MediaDescription{ MediaName: psdp.MediaName{ @@ -211,32 +156,32 @@ func (t *TrackAAC) MediaDescription() *psdp.MediaDescription { Attributes: []psdp.Attribute{ { Key: "rtpmap", - Value: typ + " mpeg4-generic/" + strconv.FormatInt(int64(t.sampleRate), 10) + - "/" + strconv.FormatInt(int64(t.channelCount), 10), + Value: typ + " mpeg4-generic/" + strconv.FormatInt(int64(t.SampleRate), 10) + + "/" + strconv.FormatInt(int64(t.ChannelCount), 10), }, { Key: "fmtp", Value: typ + " profile-level-id=1; " + "mode=AAC-hbr; " + func() string { - if t.sizeLength > 0 { - return fmt.Sprintf("sizelength=%d; ", t.sizeLength) + if t.SizeLength > 0 { + return fmt.Sprintf("sizelength=%d; ", t.SizeLength) } return "" }() + func() string { - if t.indexLength > 0 { - return fmt.Sprintf("indexlength=%d; ", t.indexLength) + if t.IndexLength > 0 { + return fmt.Sprintf("indexlength=%d; ", t.IndexLength) } return "" }() + func() string { - if t.indexDeltaLength > 0 { - return fmt.Sprintf("indexdeltalength=%d; ", t.indexDeltaLength) + if t.IndexDeltaLength > 0 { + return fmt.Sprintf("indexdeltalength=%d; ", t.IndexDeltaLength) } return "" }() + - "config=" + hex.EncodeToString(t.mpegConf), + "config=" + hex.EncodeToString(mpegConf), }, { Key: "control", diff --git a/track_aac_test.go b/track_aac_test.go index 3e69a921..a6a39d8f 100644 --- a/track_aac_test.go +++ b/track_aac_test.go @@ -7,27 +7,17 @@ import ( "github.com/stretchr/testify/require" ) -func TestTrackAACNew(t *testing.T) { - track, err := NewTrackAAC(96, 2, 48000, 4, []byte{0x01, 0x02}, 13, 3, 3) - require.NoError(t, err) - require.Equal(t, "", track.GetControl()) - require.Equal(t, 2, track.Type()) - require.Equal(t, 48000, track.ClockRate()) - require.Equal(t, 4, track.ChannelCount()) - require.Equal(t, []byte{0x01, 0x02}, track.AOTSpecificConfig()) - require.Equal(t, 13, track.SizeLength()) - require.Equal(t, 3, track.IndexLength()) - require.Equal(t, 3, track.IndexDeltaLength()) -} - -func TestTrackAACNewErrors(t *testing.T) { - _, err := NewTrackAAC(96, 2, 48000, 10, nil, 13, 3, 3) - require.EqualError(t, err, "invalid configuration: invalid channel count (10)") -} - func TestTrackAACClone(t *testing.T) { - track, err := NewTrackAAC(96, 2, 48000, 2, []byte{0x01, 0x02}, 13, 3, 3) - require.NoError(t, err) + track := &TrackAAC{ + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + AOTSpecificConfig: []byte{0x01, 0x02}, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, + } clone := track.clone() require.NotSame(t, track, clone) @@ -35,8 +25,15 @@ func TestTrackAACClone(t *testing.T) { } func TestTrackAACMediaDescription(t *testing.T) { - track, err := NewTrackAAC(96, 2, 48000, 2, nil, 13, 3, 3) - require.NoError(t, err) + track := &TrackAAC{ + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, + } require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_generic.go b/track_generic.go index 64f179d1..cf9071e0 100644 --- a/track_generic.go +++ b/track_generic.go @@ -61,28 +61,12 @@ func trackGenericGetClockRate(formats []string, rtpmap string) (int, error) { // TrackGeneric is a generic track. type TrackGeneric struct { + Media string + Formats []string + RTPMap string + FMTP string + trackBase - clockRate int - media string - formats []string - rtpmap string - fmtp string -} - -// NewTrackGeneric allocates a generic track. -func NewTrackGeneric(media string, formats []string, rtpmap string, fmtp string) (*TrackGeneric, error) { - clockRate, err := trackGenericGetClockRate(formats, rtpmap) - if err != nil { - return nil, fmt.Errorf("unable to get clock rate: %s", err) - } - - return &TrackGeneric{ - clockRate: clockRate, - media: media, - formats: formats, - rtpmap: rtpmap, - fmtp: fmtp, - }, nil } func newTrackGenericFromMediaDescription( @@ -98,7 +82,7 @@ func newTrackGenericFromMediaDescription( return "" }() - clockRate, err := trackGenericGetClockRate(md.MediaName.Formats, rtpmap) + _, err := trackGenericGetClockRate(md.MediaName.Formats, rtpmap) if err != nil { return nil, fmt.Errorf("unable to get clock rate: %s", err) } @@ -113,30 +97,29 @@ func newTrackGenericFromMediaDescription( }() return &TrackGeneric{ + Media: md.MediaName.Media, + Formats: md.MediaName.Formats, + RTPMap: rtpmap, + FMTP: fmtp, trackBase: trackBase{ control: control, }, - clockRate: clockRate, - media: md.MediaName.Media, - formats: md.MediaName.Formats, - rtpmap: rtpmap, - fmtp: fmtp, }, nil } // ClockRate returns the track clock rate. func (t *TrackGeneric) ClockRate() int { - return t.clockRate + clockRate, _ := trackGenericGetClockRate(t.Formats, t.RTPMap) + return clockRate } func (t *TrackGeneric) clone() Track { return &TrackGeneric{ + Media: t.Media, + Formats: t.Formats, + RTPMap: t.RTPMap, + FMTP: t.FMTP, trackBase: t.trackBase, - clockRate: t.clockRate, - media: t.media, - formats: t.formats, - rtpmap: t.rtpmap, - fmtp: t.fmtp, } } @@ -144,24 +127,24 @@ func (t *TrackGeneric) clone() Track { func (t *TrackGeneric) MediaDescription() *psdp.MediaDescription { return &psdp.MediaDescription{ MediaName: psdp.MediaName{ - Media: t.media, + Media: t.Media, Protos: []string{"RTP", "AVP"}, - Formats: t.formats, + Formats: t.Formats, }, Attributes: func() []psdp.Attribute { var ret []psdp.Attribute - if t.rtpmap != "" { + if t.RTPMap != "" { ret = append(ret, psdp.Attribute{ Key: "rtpmap", - Value: t.rtpmap, + Value: t.RTPMap, }) } - if t.fmtp != "" { + if t.FMTP != "" { ret = append(ret, psdp.Attribute{ Key: "fmtp", - Value: t.fmtp, + Value: t.FMTP, }) } diff --git a/track_generic_test.go b/track_generic_test.go index 8e5d0aeb..1d4c6827 100644 --- a/track_generic_test.go +++ b/track_generic_test.go @@ -7,38 +7,14 @@ import ( "github.com/stretchr/testify/require" ) -func TestTrackGenericNew(t *testing.T) { - track, err := NewTrackGeneric( - "video", - []string{"100", "101"}, - "98 H265/90000", - "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; "+ - "sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=", - ) - require.NoError(t, err) - require.Equal(t, "", track.GetControl()) - require.Equal(t, 90000, track.ClockRate()) -} - -func TestTrackGenericNewErrors(t *testing.T) { - _, err := NewTrackGeneric( - "video", - []string{"100", "101"}, - "98 H265/", - "", - ) - require.EqualError(t, err, "unable to get clock rate: strconv.ParseInt: parsing \"\": invalid syntax") -} - func TestTrackGenericClone(t *testing.T) { - track, err := NewTrackGeneric( - "video", - []string{"100", "101"}, - "98 H265/90000", - "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; "+ + track := &TrackGeneric{ + Media: "video", + Formats: []string{"100", "101"}, + RTPMap: "98 H265/90000", + FMTP: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " + "sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=", - ) - require.NoError(t, err) + } clone := track.clone() require.NotSame(t, track, clone) @@ -46,14 +22,13 @@ func TestTrackGenericClone(t *testing.T) { } func TestTrackGenericMediaDescription(t *testing.T) { - track, err := NewTrackGeneric( - "video", - []string{"100", "101"}, - "98 H265/90000", - "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; "+ + track := &TrackGeneric{ + Media: "video", + Formats: []string{"100", "101"}, + RTPMap: "98 H265/90000", + FMTP: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " + "sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=", - ) - require.NoError(t, err) + } require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ Media: "video", diff --git a/track_h264.go b/track_h264.go index f8d898d0..d41ea933 100644 --- a/track_h264.go +++ b/track_h264.go @@ -13,22 +13,13 @@ import ( // TrackH264 is a H264 track. type TrackH264 struct { - trackBase - payloadType uint8 - sps []byte - pps []byte - extradata []byte - mutex sync.RWMutex -} + PayloadType uint8 + SPS []byte + PPS []byte + Extradata []byte -// NewTrackH264 allocates a TrackH264. -func NewTrackH264(payloadType uint8, sps []byte, pps []byte, extradata []byte) (*TrackH264, error) { - return &TrackH264{ - payloadType: payloadType, - sps: sps, - pps: pps, - extradata: extradata, - }, nil + trackBase + mutex sync.RWMutex } func newTrackH264FromMediaDescription( @@ -37,10 +28,10 @@ func newTrackH264FromMediaDescription( md *psdp.MediaDescription, ) (*TrackH264, error) { t := &TrackH264{ + PayloadType: payloadType, trackBase: trackBase{ control: control, }, - payloadType: payloadType, } t.fillParamsFromMediaDescription(md) @@ -96,9 +87,9 @@ func (t *TrackH264) fillParamsFromMediaDescription(md *psdp.MediaDescription) er } } - t.sps = sps - t.pps = pps - t.extradata = extradata + t.SPS = sps + t.PPS = pps + t.Extradata = extradata return nil } } @@ -113,45 +104,40 @@ func (t *TrackH264) ClockRate() int { func (t *TrackH264) clone() Track { return &TrackH264{ + PayloadType: t.PayloadType, + SPS: t.SPS, + PPS: t.PPS, + Extradata: t.Extradata, trackBase: t.trackBase, - payloadType: t.payloadType, - sps: t.sps, - pps: t.pps, - extradata: t.extradata, } } -// SPS returns the track SPS. -func (t *TrackH264) SPS() []byte { +// SafeSPS returns the track SPS. +func (t *TrackH264) SafeSPS() []byte { t.mutex.RLock() defer t.mutex.RUnlock() - return t.sps + return t.SPS } -// PPS returns the track PPS. -func (t *TrackH264) PPS() []byte { +// SafePPS returns the track PPS. +func (t *TrackH264) SafePPS() []byte { t.mutex.RLock() defer t.mutex.RUnlock() - return t.pps + return t.PPS } -// ExtraData returns the track extra data. -func (t *TrackH264) ExtraData() []byte { - return t.extradata -} - -// SetSPS sets the track SPS. -func (t *TrackH264) SetSPS(v []byte) { +// SafeSetSPS sets the track SPS. +func (t *TrackH264) SafeSetSPS(v []byte) { t.mutex.Lock() defer t.mutex.Unlock() - t.sps = v + t.SPS = v } -// SetPPS sets the track PPS. -func (t *TrackH264) SetPPS(v []byte) { +// SafeSetPPS sets the track PPS. +func (t *TrackH264) SafeSetPPS(v []byte) { t.mutex.Lock() defer t.mutex.Unlock() - t.pps = v + t.PPS = v } // MediaDescription returns the track media description in SDP format. @@ -159,24 +145,24 @@ func (t *TrackH264) MediaDescription() *psdp.MediaDescription { t.mutex.RLock() defer t.mutex.RUnlock() - typ := strconv.FormatInt(int64(t.payloadType), 10) + typ := strconv.FormatInt(int64(t.PayloadType), 10) fmtp := typ + " packetization-mode=1" var tmp []string - if t.sps != nil { - tmp = append(tmp, base64.StdEncoding.EncodeToString(t.sps)) + if t.SPS != nil { + tmp = append(tmp, base64.StdEncoding.EncodeToString(t.SPS)) } - if t.pps != nil { - tmp = append(tmp, base64.StdEncoding.EncodeToString(t.pps)) + if t.PPS != nil { + tmp = append(tmp, base64.StdEncoding.EncodeToString(t.PPS)) } - if t.extradata != nil { - tmp = append(tmp, base64.StdEncoding.EncodeToString(t.extradata)) + if t.Extradata != nil { + tmp = append(tmp, base64.StdEncoding.EncodeToString(t.Extradata)) } fmtp += "; sprop-parameter-sets=" + strings.Join(tmp, ",") - if len(t.sps) >= 4 { - fmtp += "; profile-level-id=" + strings.ToUpper(hex.EncodeToString(t.sps[1:4])) + if len(t.SPS) >= 4 { + fmtp += "; profile-level-id=" + strings.ToUpper(hex.EncodeToString(t.SPS[1:4])) } return &psdp.MediaDescription{ diff --git a/track_h264_test.go b/track_h264_test.go index afa30203..f1cdc37b 100644 --- a/track_h264_test.go +++ b/track_h264_test.go @@ -165,19 +165,30 @@ func TestTrackH264GetSPSPPSErrors(t *testing.T) { } } -func TestTrackH264New(t *testing.T) { - track, err := NewTrackH264(96, - []byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06}) - require.NoError(t, err) +func TestTrackH264Params(t *testing.T) { + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02}, + PPS: []byte{0x03, 0x04}, + Extradata: []byte{0x05, 0x06}, + } require.Equal(t, "", track.GetControl()) - require.Equal(t, []byte{0x01, 0x02}, track.SPS()) - require.Equal(t, []byte{0x03, 0x04}, track.PPS()) - require.Equal(t, []byte{0x05, 0x06}, track.ExtraData()) + require.Equal(t, []byte{0x01, 0x02}, track.SafeSPS()) + require.Equal(t, []byte{0x03, 0x04}, track.SafePPS()) + + track.SafeSetSPS([]byte{0x07, 0x08}) + track.SafeSetPPS([]byte{0x09, 0x0A}) + require.Equal(t, []byte{0x07, 0x08}, track.SafeSPS()) + require.Equal(t, []byte{0x09, 0x0A}, track.SafePPS()) } func TestTrackH264Clone(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06}) - require.NoError(t, err) + track := &TrackH264{ + PayloadType: 96, + SPS: []byte{0x01, 0x02}, + PPS: []byte{0x03, 0x04}, + Extradata: []byte{0x05, 0x06}, + } clone := track.clone() require.NotSame(t, track, clone) @@ -185,19 +196,20 @@ func TestTrackH264Clone(t *testing.T) { } func TestTrackH264MediaDescription(t *testing.T) { - track, err := NewTrackH264(96, - []byte{ + track := &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, }, - []byte{ + Extradata: []byte{ 0x01, 0x02, - }) - require.NoError(t, err) + }, + } require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_h265.go b/track_h265.go index 599fcc47..50fd1e06 100644 --- a/track_h265.go +++ b/track_h265.go @@ -12,22 +12,13 @@ import ( // TrackH265 is a H265 track. type TrackH265 struct { - trackBase - payloadType uint8 - vps []byte - sps []byte - pps []byte - mutex sync.RWMutex -} + PayloadType uint8 + VPS []byte + SPS []byte + PPS []byte -// NewTrackH265 allocates a TrackH265. -func NewTrackH265(payloadType uint8, vps []byte, sps []byte, pps []byte) *TrackH265 { - return &TrackH265{ - payloadType: payloadType, - vps: vps, - sps: sps, - pps: pps, - } + trackBase + mutex sync.RWMutex } func newTrackH265FromMediaDescription( @@ -36,10 +27,10 @@ func newTrackH265FromMediaDescription( md *psdp.MediaDescription, ) (*TrackH265, error) { t := &TrackH265{ + PayloadType: payloadType, trackBase: trackBase{ control: control, }, - payloadType: payloadType, } t.fillParamsFromMediaDescription(md) @@ -73,21 +64,21 @@ func (t *TrackH265) fillParamsFromMediaDescription(md *psdp.MediaDescription) er switch tmp[0] { case "sprop-vps": var err error - t.vps, err = base64.StdEncoding.DecodeString(tmp[1]) + t.VPS, err = base64.StdEncoding.DecodeString(tmp[1]) if err != nil { return fmt.Errorf("invalid sprop-vps (%v)", v) } case "sprop-sps": var err error - t.sps, err = base64.StdEncoding.DecodeString(tmp[1]) + t.SPS, err = base64.StdEncoding.DecodeString(tmp[1]) if err != nil { return fmt.Errorf("invalid sprop-sps (%v)", v) } case "sprop-pps": var err error - t.pps, err = base64.StdEncoding.DecodeString(tmp[1]) + t.PPS, err = base64.StdEncoding.DecodeString(tmp[1]) if err != nil { return fmt.Errorf("invalid sprop-pps (%v)", v) } @@ -104,54 +95,54 @@ func (t *TrackH265) ClockRate() int { func (t *TrackH265) clone() Track { return &TrackH265{ + PayloadType: t.PayloadType, + VPS: t.VPS, + SPS: t.SPS, + PPS: t.PPS, trackBase: t.trackBase, - payloadType: t.payloadType, - vps: t.vps, - sps: t.sps, - pps: t.pps, } } -// VPS returns the track VPS. -func (t *TrackH265) VPS() []byte { +// SafeVPS returns the track VPS. +func (t *TrackH265) SafeVPS() []byte { t.mutex.RLock() defer t.mutex.RUnlock() - return t.vps + return t.VPS } -// SPS returns the track SPS. -func (t *TrackH265) SPS() []byte { +// SafeSPS returns the track SPS. +func (t *TrackH265) SafeSPS() []byte { t.mutex.RLock() defer t.mutex.RUnlock() - return t.sps + return t.SPS } -// PPS returns the track PPS. -func (t *TrackH265) PPS() []byte { +// SafePPS returns the track PPS. +func (t *TrackH265) SafePPS() []byte { t.mutex.RLock() defer t.mutex.RUnlock() - return t.pps + return t.PPS } -// SetVPS sets the track VPS. -func (t *TrackH265) SetVPS(v []byte) { +// SafeSetVPS sets the track VPS. +func (t *TrackH265) SafeSetVPS(v []byte) { t.mutex.Lock() defer t.mutex.Unlock() - t.vps = v + t.VPS = v } -// SetSPS sets the track SPS. -func (t *TrackH265) SetSPS(v []byte) { +// SafeSetSPS sets the track SPS. +func (t *TrackH265) SafeSetSPS(v []byte) { t.mutex.Lock() defer t.mutex.Unlock() - t.sps = v + t.SPS = v } -// SetPPS sets the track PPS. -func (t *TrackH265) SetPPS(v []byte) { +// SafeSetPPS sets the track PPS. +func (t *TrackH265) SafeSetPPS(v []byte) { t.mutex.Lock() defer t.mutex.Unlock() - t.pps = v + t.PPS = v } // MediaDescription returns the track media description in SDP format. @@ -159,19 +150,19 @@ func (t *TrackH265) MediaDescription() *psdp.MediaDescription { t.mutex.RLock() defer t.mutex.RUnlock() - typ := strconv.FormatInt(int64(t.payloadType), 10) + typ := strconv.FormatInt(int64(t.PayloadType), 10) fmtp := typ var tmp []string - if t.vps != nil { - tmp = append(tmp, "sprop-vps="+base64.StdEncoding.EncodeToString(t.vps)) + if t.VPS != nil { + tmp = append(tmp, "sprop-vps="+base64.StdEncoding.EncodeToString(t.VPS)) } - if t.sps != nil { - tmp = append(tmp, "sprop-sps="+base64.StdEncoding.EncodeToString(t.sps)) + if t.SPS != nil { + tmp = append(tmp, "sprop-sps="+base64.StdEncoding.EncodeToString(t.SPS)) } - if t.pps != nil { - tmp = append(tmp, "sprop-pps="+base64.StdEncoding.EncodeToString(t.pps)) + if t.PPS != nil { + tmp = append(tmp, "sprop-pps="+base64.StdEncoding.EncodeToString(t.PPS)) } if tmp != nil { fmtp += " " + strings.Join(tmp, "; ") diff --git a/track_h265_test.go b/track_h265_test.go index 558e3407..479ad607 100644 --- a/track_h265_test.go +++ b/track_h265_test.go @@ -7,17 +7,33 @@ import ( "github.com/stretchr/testify/require" ) -func TestTrackH265New(t *testing.T) { - track := NewTrackH265(96, - []byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06}) +func TestTrackH265Params(t *testing.T) { + track := &TrackH265{ + PayloadType: 96, + VPS: []byte{0x01, 0x02}, + SPS: []byte{0x03, 0x04}, + PPS: []byte{0x05, 0x06}, + } require.Equal(t, "", track.GetControl()) - require.Equal(t, []byte{0x01, 0x02}, track.VPS()) - require.Equal(t, []byte{0x03, 0x04}, track.SPS()) - require.Equal(t, []byte{0x05, 0x06}, track.PPS()) + require.Equal(t, []byte{0x01, 0x02}, track.SafeVPS()) + require.Equal(t, []byte{0x03, 0x04}, track.SafeSPS()) + require.Equal(t, []byte{0x05, 0x06}, track.SafePPS()) + + track.SafeSetVPS([]byte{0x07, 0x08}) + track.SafeSetSPS([]byte{0x09, 0x0A}) + track.SafeSetPPS([]byte{0x0B, 0x0C}) + require.Equal(t, []byte{0x07, 0x08}, track.SafeVPS()) + require.Equal(t, []byte{0x09, 0x0A}, track.SafeSPS()) + require.Equal(t, []byte{0x0B, 0x0C}, track.SafePPS()) } func TestTrackH265Clone(t *testing.T) { - track := NewTrackH265(96, []byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06}) + track := &TrackH265{ + PayloadType: 96, + VPS: []byte{0x01, 0x02}, + SPS: []byte{0x03, 0x04}, + PPS: []byte{0x05, 0x06}, + } clone := track.clone() require.NotSame(t, track, clone) @@ -25,7 +41,12 @@ func TestTrackH265Clone(t *testing.T) { } func TestTrackH265MediaDescription(t *testing.T) { - track := NewTrackH265(96, []byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06}) + track := &TrackH265{ + PayloadType: 96, + VPS: []byte{0x01, 0x02}, + SPS: []byte{0x03, 0x04}, + PPS: []byte{0x05, 0x06}, + } require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_jpeg.go b/track_jpeg.go index 2dddce59..079a5036 100644 --- a/track_jpeg.go +++ b/track_jpeg.go @@ -9,11 +9,6 @@ type TrackJPEG struct { trackBase } -// NewTrackJPEG allocates a TrackJPEG. -func NewTrackJPEG() *TrackJPEG { - return &TrackJPEG{} -} - func newTrackJPEGFromMediaDescription( control string) (*TrackJPEG, error, ) { diff --git a/track_jpeg_test.go b/track_jpeg_test.go index 9d324073..4b4bc42f 100644 --- a/track_jpeg_test.go +++ b/track_jpeg_test.go @@ -7,13 +7,8 @@ import ( "github.com/stretchr/testify/require" ) -func TestTrackJPEGNew(t *testing.T) { - track := NewTrackJPEG() - require.Equal(t, "", track.GetControl()) -} - func TestTrackJPEGClone(t *testing.T) { - track := NewTrackJPEG() + track := &TrackJPEG{} clone := track.clone() require.NotSame(t, track, clone) @@ -21,7 +16,7 @@ func TestTrackJPEGClone(t *testing.T) { } func TestTrackJPEGMediaDescription(t *testing.T) { - track := NewTrackJPEG() + track := &TrackJPEG{} require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_mpegaudio.go b/track_mpegaudio.go index 4bca7f70..5e523330 100644 --- a/track_mpegaudio.go +++ b/track_mpegaudio.go @@ -9,11 +9,6 @@ type TrackMpegAudio struct { trackBase } -// NewTrackMpegAudio allocates a TrackMpegAudio. -func NewTrackMpegAudio() *TrackMpegAudio { - return &TrackMpegAudio{} -} - func newTrackMpegAudioFromMediaDescription( control string) (*TrackMpegAudio, error, ) { diff --git a/track_mpegaudio_test.go b/track_mpegaudio_test.go index 0d739f62..b95669eb 100644 --- a/track_mpegaudio_test.go +++ b/track_mpegaudio_test.go @@ -8,12 +8,12 @@ import ( ) func TestTrackMpegAudioNew(t *testing.T) { - track := NewTrackMpegAudio() + track := &TrackMpegAudio{} require.Equal(t, "", track.GetControl()) } func TestTrackMpegAudioClone(t *testing.T) { - track := NewTrackMpegAudio() + track := &TrackMpegAudio{} clone := track.clone() require.NotSame(t, track, clone) @@ -21,7 +21,7 @@ func TestTrackMpegAudioClone(t *testing.T) { } func TestTrackMpegAudioMediaDescription(t *testing.T) { - track := NewTrackMpegAudio() + track := &TrackMpegAudio{} require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_mpegvideo.go b/track_mpegvideo.go index b5331e0d..f3797955 100644 --- a/track_mpegvideo.go +++ b/track_mpegvideo.go @@ -9,11 +9,6 @@ type TrackMpegVideo struct { trackBase } -// NewTrackMpegVideo allocates a TrackMpegVideo. -func NewTrackMpegVideo() *TrackMpegVideo { - return &TrackMpegVideo{} -} - func newTrackMpegVideoFromMediaDescription( control string) (*TrackMpegVideo, error, ) { diff --git a/track_mpegvideo_test.go b/track_mpegvideo_test.go index a446173d..e08e4c53 100644 --- a/track_mpegvideo_test.go +++ b/track_mpegvideo_test.go @@ -8,12 +8,12 @@ import ( ) func TestTrackMpegVideoNew(t *testing.T) { - track := NewTrackMpegVideo() + track := &TrackMpegVideo{} require.Equal(t, "", track.GetControl()) } func TestTrackMpegVideoClone(t *testing.T) { - track := NewTrackMpegVideo() + track := &TrackMpegVideo{} clone := track.clone() require.NotSame(t, track, clone) @@ -21,7 +21,7 @@ func TestTrackMpegVideoClone(t *testing.T) { } func TestTrackMpegVideoMediaDescription(t *testing.T) { - track := NewTrackMpegVideo() + track := &TrackMpegVideo{} require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_opus.go b/track_opus.go index 926a6058..6f574c69 100644 --- a/track_opus.go +++ b/track_opus.go @@ -10,19 +10,11 @@ import ( // TrackOpus is a Opus track. type TrackOpus struct { - trackBase - payloadType uint8 - sampleRate int - channelCount int -} + PayloadType uint8 + SampleRate int + ChannelCount int -// NewTrackOpus allocates a TrackOpus. -func NewTrackOpus(payloadType uint8, sampleRate int, channelCount int) *TrackOpus { - return &TrackOpus{ - payloadType: payloadType, - sampleRate: sampleRate, - channelCount: channelCount, - } + trackBase } func newTrackOpusFromMediaDescription( @@ -47,37 +39,32 @@ func newTrackOpusFromMediaDescription( } return &TrackOpus{ + PayloadType: payloadType, + SampleRate: int(sampleRate), + ChannelCount: int(channelCount), trackBase: trackBase{ control: control, }, - payloadType: payloadType, - sampleRate: int(sampleRate), - channelCount: int(channelCount), }, nil } // ClockRate returns the track clock rate. func (t *TrackOpus) ClockRate() int { - return t.sampleRate + return t.SampleRate } func (t *TrackOpus) clone() Track { return &TrackOpus{ + PayloadType: t.PayloadType, + SampleRate: t.SampleRate, + ChannelCount: t.ChannelCount, trackBase: t.trackBase, - payloadType: t.payloadType, - sampleRate: t.sampleRate, - channelCount: t.channelCount, } } -// ChannelCount returns the channel count. -func (t *TrackOpus) ChannelCount() int { - return t.channelCount -} - // MediaDescription returns the track media description in SDP format. func (t *TrackOpus) MediaDescription() *psdp.MediaDescription { - typ := strconv.FormatInt(int64(t.payloadType), 10) + typ := strconv.FormatInt(int64(t.PayloadType), 10) return &psdp.MediaDescription{ MediaName: psdp.MediaName{ @@ -88,13 +75,13 @@ func (t *TrackOpus) MediaDescription() *psdp.MediaDescription { Attributes: []psdp.Attribute{ { Key: "rtpmap", - Value: typ + " opus/" + strconv.FormatInt(int64(t.sampleRate), 10) + - "/" + strconv.FormatInt(int64(t.channelCount), 10), + Value: typ + " opus/" + strconv.FormatInt(int64(t.SampleRate), 10) + + "/" + strconv.FormatInt(int64(t.ChannelCount), 10), }, { Key: "fmtp", Value: typ + " sprop-stereo=" + func() string { - if t.channelCount == 2 { + if t.ChannelCount == 2 { return "1" } return "0" diff --git a/track_opus_test.go b/track_opus_test.go index 5fe9290b..e87e5342 100644 --- a/track_opus_test.go +++ b/track_opus_test.go @@ -7,15 +7,12 @@ import ( "github.com/stretchr/testify/require" ) -func TestTrackOpusNew(t *testing.T) { - track := NewTrackOpus(96, 48000, 2) - require.Equal(t, "", track.GetControl()) - require.Equal(t, 48000, track.ClockRate()) - require.Equal(t, 2, track.ChannelCount()) -} - func TestTracOpusClone(t *testing.T) { - track := NewTrackOpus(96, 96000, 4) + track := &TrackOpus{ + PayloadType: 96, + SampleRate: 48000, + ChannelCount: 2, + } clone := track.clone() require.NotSame(t, track, clone) @@ -23,7 +20,11 @@ func TestTracOpusClone(t *testing.T) { } func TestTrackOpusMediaDescription(t *testing.T) { - track := NewTrackOpus(96, 48000, 2) + track := &TrackOpus{ + PayloadType: 96, + SampleRate: 48000, + ChannelCount: 2, + } require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_pcma.go b/track_pcma.go index baee2ef2..734a27dc 100644 --- a/track_pcma.go +++ b/track_pcma.go @@ -12,11 +12,6 @@ type TrackPCMA struct { trackBase } -// NewTrackPCMA allocates a TrackPCMA. -func NewTrackPCMA() *TrackPCMA { - return &TrackPCMA{} -} - func newTrackPCMAFromMediaDescription( control string, rtpmapPart1 string) (*TrackPCMA, error, diff --git a/track_pcma_test.go b/track_pcma_test.go index ce8a194e..f78df502 100644 --- a/track_pcma_test.go +++ b/track_pcma_test.go @@ -8,12 +8,12 @@ import ( ) func TestTrackPCMANew(t *testing.T) { - track := NewTrackPCMA() + track := &TrackPCMA{} require.Equal(t, "", track.GetControl()) } func TestTrackPCMAClone(t *testing.T) { - track := NewTrackPCMA() + track := &TrackPCMA{} clone := track.clone() require.NotSame(t, track, clone) @@ -21,7 +21,7 @@ func TestTrackPCMAClone(t *testing.T) { } func TestTrackPCMAMediaDescription(t *testing.T) { - track := NewTrackPCMA() + track := &TrackPCMA{} require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_pcmu.go b/track_pcmu.go index 7e0c9d25..b41400b7 100644 --- a/track_pcmu.go +++ b/track_pcmu.go @@ -12,11 +12,6 @@ type TrackPCMU struct { trackBase } -// NewTrackPCMU allocates a TrackPCMU. -func NewTrackPCMU() *TrackPCMU { - return &TrackPCMU{} -} - func newTrackPCMUFromMediaDescription( control string, rtpmapPart1 string) (*TrackPCMU, error, diff --git a/track_pcmu_test.go b/track_pcmu_test.go index 7e2c5a61..dae4a871 100644 --- a/track_pcmu_test.go +++ b/track_pcmu_test.go @@ -8,12 +8,12 @@ import ( ) func TestTrackPCMUNew(t *testing.T) { - track := NewTrackPCMU() + track := &TrackPCMU{} require.Equal(t, "", track.GetControl()) } func TestTrackPCMUClone(t *testing.T) { - track := NewTrackPCMU() + track := &TrackPCMU{} clone := track.clone() require.NotSame(t, track, clone) @@ -21,7 +21,7 @@ func TestTrackPCMUClone(t *testing.T) { } func TestTrackPCMUMediaDescription(t *testing.T) { - track := NewTrackPCMU() + track := &TrackPCMU{} require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/track_test.go b/track_test.go index fb0c7d90..7cbade55 100644 --- a/track_test.go +++ b/track_test.go @@ -72,15 +72,14 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackAAC{ - payloadType: 96, - typ: 2, - sampleRate: 48000, - channelCount: 2, - aotSpecificConfig: []byte{0x01, 0x02}, - mpegConf: []byte{0x11, 0x90, 0x08, 0x10}, - sizeLength: 13, - indexLength: 3, - indexDeltaLength: 3, + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + AOTSpecificConfig: []byte{0x01, 0x02}, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, }, }, { @@ -103,14 +102,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackAAC{ - payloadType: 96, - typ: 2, - sampleRate: 48000, - channelCount: 2, - mpegConf: []byte{0x11, 0x90}, - sizeLength: 13, - indexLength: 3, - indexDeltaLength: 3, + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, }, }, { @@ -133,14 +131,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackAAC{ - payloadType: 96, - typ: 2, - sampleRate: 48000, - channelCount: 2, - mpegConf: []byte{0x11, 0x90}, - sizeLength: 13, - indexLength: 3, - indexDeltaLength: 3, + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, }, }, { @@ -167,14 +164,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackAAC{ - payloadType: 96, - typ: 2, - sampleRate: 48000, - channelCount: 2, - mpegConf: []byte{0x11, 0x90}, - sizeLength: 13, - indexLength: 0, - indexDeltaLength: 0, + PayloadType: 96, + Type: 2, + SampleRate: 48000, + ChannelCount: 2, + SizeLength: 13, + IndexLength: 0, + IndexDeltaLength: 0, }, }, { @@ -197,9 +193,9 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackOpus{ - payloadType: 96, - sampleRate: 48000, - channelCount: 2, + PayloadType: 96, + SampleRate: 48000, + ChannelCount: 2, }, }, { @@ -245,13 +241,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackH264{ - payloadType: 96, - sps: []byte{ + 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, }, - pps: []byte{ + PPS: []byte{ 0x68, 0xee, 0x3c, 0x80, }, }, @@ -272,7 +268,7 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackH264{ - payloadType: 96, + PayloadType: 96, }, }, { @@ -296,14 +292,14 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackH264{ - payloadType: 96, - sps: []byte{ + PayloadType: 96, + SPS: []byte{ 0x67, 0x64, 0x00, 0x1f, 0xac, 0xd9, 0x40, 0x50, 0x05, 0xbb, 0x01, 0x6c, 0x80, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x1e, 0x07, 0x8c, 0x18, 0xcb, }, - pps: []byte{ + PPS: []byte{ 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0, }, }, @@ -329,17 +325,17 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackH264{ - payloadType: 96, - sps: []byte{ + PayloadType: 96, + SPS: []byte{ 0x67, 0x64, 0x00, 0x29, 0xac, 0x13, 0x31, 0x40, 0x78, 0x04, 0x47, 0xde, 0x03, 0xea, 0x02, 0x02, 0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x06, 0x52, 0x80, }, - pps: []byte{ + PPS: []byte{ 0x68, 0xfa, 0x8f, 0x2c, }, - extradata: []byte{ + Extradata: []byte{ 0x68, 0xfa, 0x8f, 0x2c, }, }, @@ -365,13 +361,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackH265{ - payloadType: 96, - vps: []byte{ + PayloadType: 96, + VPS: []byte{ 0x40, 0x1, 0xc, 0x1, 0xff, 0xff, 0x1, 0x60, 0x0, 0x0, 0x3, 0x0, 0x90, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x78, 0x99, 0x98, 0x9, }, - sps: []byte{ + SPS: []byte{ 0x42, 0x1, 0x1, 0x1, 0x60, 0x0, 0x0, 0x3, 0x0, 0x90, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x78, 0xa0, 0x3, 0xc0, 0x80, 0x10, 0xe5, @@ -379,7 +375,7 @@ func TestTrackNewFromMediaDescription(t *testing.T) { 0x0, 0x3, 0x0, 0x10, 0x0, 0x0, 0x3, 0x1, 0xe0, 0x80, }, - pps: []byte{ + PPS: []byte{ 0x44, 0x1, 0xc1, 0x72, 0xb4, 0x62, 0x40, }, }, @@ -397,10 +393,26 @@ func TestTrackNewFromMediaDescription(t *testing.T) { Key: "rtpmap", Value: "96 VP9/90000", }, + { + Key: "fmtp", + Value: "96 max-fr=123;max-fs=456;profile-id=789", + }, }, }, &TrackVP9{ - payloadType: 96, + PayloadType: 96, + MaxFR: func() *int { + v := 123 + return &v + }(), + MaxFS: func() *int { + v := 456 + return &v + }(), + ProfileID: func() *int { + v := 789 + return &v + }(), }, }, { @@ -424,11 +436,10 @@ func TestTrackNewFromMediaDescription(t *testing.T) { }, }, &TrackGeneric{ - clockRate: 90000, - media: "video", - formats: []string{"98", "96"}, - rtpmap: "98 H265/90000", - fmtp: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " + + Media: "video", + Formats: []string{"98", "96"}, + RTPMap: "98 H265/90000", + FMTP: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " + "sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=", }, }, @@ -834,8 +845,7 @@ func TestTrackURL(t *testing.T) { } func TestTrackURLError(t *testing.T) { - track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x05, 0x06, 0x07, 0x08}, nil) - require.NoError(t, err) - _, err = track.url(nil) + track := &TrackH264{} + _, err := track.url(nil) require.EqualError(t, err, "Content-Base header not provided") } diff --git a/track_vp9.go b/track_vp9.go index de2e613d..0857a797 100644 --- a/track_vp9.go +++ b/track_vp9.go @@ -11,20 +11,10 @@ import ( // TrackVP9 is a VP9 track. type TrackVP9 struct { trackBase - payloadType uint8 - maxFR *int - maxFS *int - profileID *int -} - -// NewTrackVP9 allocates a TrackVP9. -func NewTrackVP9(payloadType uint8, maxFR *int, maxFS *int, profileID *int) *TrackVP9 { - return &TrackVP9{ - payloadType: payloadType, - maxFR: maxFR, - maxFS: maxFS, - profileID: profileID, - } + PayloadType uint8 + MaxFR *int + MaxFS *int + ProfileID *int } func newTrackVP9FromMediaDescription( @@ -33,10 +23,10 @@ func newTrackVP9FromMediaDescription( md *psdp.MediaDescription, ) (*TrackVP9, error) { t := &TrackVP9{ + PayloadType: payloadType, trackBase: trackBase{ control: control, }, - payloadType: payloadType, } t.fillParamsFromMediaDescription(md) @@ -74,7 +64,7 @@ func (t *TrackVP9) fillParamsFromMediaDescription(md *psdp.MediaDescription) err return fmt.Errorf("invalid max-fr (%v)", tmp[1]) } v2 := int(val) - t.maxFR = &v2 + t.MaxFR = &v2 case "max-fs": val, err := strconv.ParseUint(tmp[1], 10, 64) @@ -82,7 +72,7 @@ func (t *TrackVP9) fillParamsFromMediaDescription(md *psdp.MediaDescription) err return fmt.Errorf("invalid max-fs (%v)", tmp[1]) } v2 := int(val) - t.maxFS = &v2 + t.MaxFS = &v2 case "profile-id": val, err := strconv.ParseUint(tmp[1], 10, 64) @@ -90,7 +80,7 @@ func (t *TrackVP9) fillParamsFromMediaDescription(md *psdp.MediaDescription) err return fmt.Errorf("invalid profile-id (%v)", tmp[1]) } v2 := int(val) - t.profileID = &v2 + t.ProfileID = &v2 } } @@ -105,43 +95,28 @@ func (t *TrackVP9) ClockRate() int { func (t *TrackVP9) clone() Track { return &TrackVP9{ trackBase: t.trackBase, - payloadType: t.payloadType, - maxFR: t.maxFR, - maxFS: t.maxFS, - profileID: t.profileID, + PayloadType: t.PayloadType, + MaxFR: t.MaxFR, + MaxFS: t.MaxFS, + ProfileID: t.ProfileID, } } -// MaxFR returns the track max-fr. -func (t *TrackVP9) MaxFR() *int { - return t.maxFR -} - -// MaxFS returns the track max-fs. -func (t *TrackVP9) MaxFS() *int { - return t.maxFS -} - -// ProfileID returns the track profile-id. -func (t *TrackVP9) ProfileID() *int { - return t.profileID -} - // MediaDescription returns the track media description in SDP format. func (t *TrackVP9) MediaDescription() *psdp.MediaDescription { - typ := strconv.FormatInt(int64(t.payloadType), 10) + typ := strconv.FormatInt(int64(t.PayloadType), 10) fmtp := typ var tmp []string - if t.maxFR != nil { - tmp = append(tmp, "max-fr="+strconv.FormatInt(int64(*t.maxFR), 10)) + if t.MaxFR != nil { + tmp = append(tmp, "max-fr="+strconv.FormatInt(int64(*t.MaxFR), 10)) } - if t.maxFS != nil { - tmp = append(tmp, "max-fs="+strconv.FormatInt(int64(*t.maxFS), 10)) + if t.MaxFS != nil { + tmp = append(tmp, "max-fs="+strconv.FormatInt(int64(*t.MaxFS), 10)) } - if t.profileID != nil { - tmp = append(tmp, "profile-id="+strconv.FormatInt(int64(*t.profileID), 10)) + if t.ProfileID != nil { + tmp = append(tmp, "profile-id="+strconv.FormatInt(int64(*t.ProfileID), 10)) } if tmp != nil { fmtp += " " + strings.Join(tmp, ";") diff --git a/track_vp9_test.go b/track_vp9_test.go index c5e85419..bf0bf252 100644 --- a/track_vp9_test.go +++ b/track_vp9_test.go @@ -7,22 +7,16 @@ import ( "github.com/stretchr/testify/require" ) -func TestTrackVP9New(t *testing.T) { - maxFR := 123 - maxFS := 456 - profileID := 789 - track := NewTrackVP9(96, &maxFR, &maxFS, &profileID) - require.Equal(t, "", track.GetControl()) - require.Equal(t, 123, *track.MaxFR()) - require.Equal(t, 456, *track.MaxFS()) - require.Equal(t, 789, *track.ProfileID()) -} - func TestTracVP9Clone(t *testing.T) { maxFR := 123 maxFS := 456 profileID := 789 - track := NewTrackVP9(96, &maxFR, &maxFS, &profileID) + track := &TrackVP9{ + PayloadType: 96, + MaxFR: &maxFR, + MaxFS: &maxFS, + ProfileID: &profileID, + } clone := track.clone() require.NotSame(t, track, clone) @@ -33,7 +27,12 @@ func TestTrackVP9MediaDescription(t *testing.T) { maxFR := 123 maxFS := 456 profileID := 789 - track := NewTrackVP9(96, &maxFR, &maxFS, &profileID) + track := &TrackVP9{ + PayloadType: 96, + MaxFR: &maxFR, + MaxFS: &maxFS, + ProfileID: &profileID, + } require.Equal(t, &psdp.MediaDescription{ MediaName: psdp.MediaName{ diff --git a/tracks_test.go b/tracks_test.go index 02251de8..5bf767b0 100644 --- a/tracks_test.go +++ b/tracks_test.go @@ -74,9 +74,9 @@ func TestTracksReadSkipGenericTracksWithoutClockRate(t *testing.T) { trackBase: trackBase{ control: "rtsp://10.0.100.50/profile5/media.smp/trackID=v", }, - payloadType: 97, - sps: []byte{0x67, 0x64, 0x00, 0x28, 0xac, 0xb4, 0x03, 0xc0, 0x11, 0x3f, 0x2a}, - pps: []byte{0x68, 0xee, 0x01, 0x9e, 0x2c}, + PayloadType: 97, + SPS: []byte{0x67, 0x64, 0x00, 0x28, 0xac, 0xb4, 0x03, 0xc0, 0x11, 0x3f, 0x2a}, + PPS: []byte{0x68, 0xee, 0x01, 0x9e, 0x2c}, }, &TrackPCMU{ trackBase: trackBase{