mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 15:16:51 +08:00
change track initialization method
This commit is contained in:
@@ -237,8 +237,11 @@ func TestClientPublishSerial(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
err = c.StartPublishing(scheme+"://localhost:8554/teststream",
|
err = c.StartPublishing(scheme+"://localhost:8554/teststream",
|
||||||
Tracks{track})
|
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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
writerDone := make(chan struct{})
|
writerDone := make(chan struct{})
|
||||||
defer func() { <-writerDone }()
|
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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
||||||
Tracks{track})
|
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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
||||||
Tracks{track})
|
Tracks{track})
|
||||||
@@ -835,8 +847,11 @@ func TestClientPublishAutomaticProtocol(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
c := Client{}
|
c := Client{}
|
||||||
|
|
||||||
@@ -975,8 +990,11 @@ func TestClientPublishRTCPReport(t *testing.T) {
|
|||||||
udpSenderReportPeriod: 1 * time.Second,
|
udpSenderReportPeriod: 1 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
||||||
Tracks{track})
|
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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
err = c.StartPublishing("rtsp://localhost:8554/teststream",
|
||||||
Tracks{track})
|
Tracks{track})
|
||||||
|
@@ -22,14 +22,33 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestClientReadTracks(t *testing.T) {
|
func TestClientReadTracks(t *testing.T) {
|
||||||
track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track1 := &TrackH264{
|
||||||
require.NoError(t, err)
|
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)
|
track2 := &TrackAAC{
|
||||||
require.NoError(t, err)
|
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)
|
track3 := &TrackAAC{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
Type: 2,
|
||||||
|
SampleRate: 96000,
|
||||||
|
ChannelCount: 2,
|
||||||
|
AOTSpecificConfig: nil,
|
||||||
|
SizeLength: 13,
|
||||||
|
IndexLength: 3,
|
||||||
|
IndexDeltaLength: 3,
|
||||||
|
}
|
||||||
|
|
||||||
l, err := net.Listen("tcp", "localhost:8554")
|
l, err := net.Listen("tcp", "localhost:8554")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -203,8 +222,11 @@ func TestClientRead(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
require.Equal(t, mustParseURL(scheme+"://"+listenIP+":8554/test/stream?param=value"), req.URL)
|
require.Equal(t, mustParseURL(scheme+"://"+listenIP+":8554/test/stream?param=value"), req.URL)
|
||||||
|
|
||||||
track, err := NewTrackGeneric("application", []string{"97"}, "97 private/90000", "")
|
track := &TrackGeneric{
|
||||||
require.NoError(t, err)
|
Media: "application",
|
||||||
|
Formats: []string{"97"},
|
||||||
|
RTPMap: "97 private/90000",
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -464,11 +486,17 @@ func TestClientReadPartial(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
require.Equal(t, mustParseURL("rtsp://"+listenIP+":8554/teststream"), req.URL)
|
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)
|
track1 := &TrackH264{
|
||||||
require.NoError(t, err)
|
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)
|
track2 := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track1, track2}
|
tracks := Tracks{track1, track2}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -617,8 +645,11 @@ func TestClientReadContentBase(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL)
|
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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -756,8 +787,11 @@ func TestClientReadAnyPort(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -915,8 +949,11 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1053,8 +1090,11 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
|
|||||||
err = v.ValidateRequest(req)
|
err = v.ValidateRequest(req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1285,8 +1325,11 @@ func TestClientReadDifferentInterleavedIDs(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL)
|
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)
|
track1 := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track1}
|
tracks := Tracks{track1}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1499,8 +1542,11 @@ func TestClientReadRedirect(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
}
|
}
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1660,8 +1706,11 @@ func TestClientReadPause(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1838,9 +1887,11 @@ func TestClientReadRTCPReport(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04},
|
track := &TrackH264{
|
||||||
[]byte{0x01, 0x02, 0x03, 0x04}, nil)
|
PayloadType: 96,
|
||||||
require.NoError(t, err)
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -2022,8 +2073,11 @@ func TestClientReadErrorTimeout(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -2176,8 +2230,11 @@ func TestClientReadIgnoreTCPInvalidTrack(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -2309,8 +2366,11 @@ func TestClientReadSeek(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -2485,8 +2545,11 @@ func TestClientReadKeepaliveFromSession(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -2616,8 +2679,11 @@ func TestClientReadDifferentSource(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
require.Equal(t, mustParseURL("rtsp://localhost:8554/test/stream?param=value"), req.URL)
|
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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
|
@@ -118,8 +118,11 @@ func TestClientSession(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, base.HeaderValue{"123456"}, req.Header["Session"])
|
require.Equal(t, base.HeaderValue{"123456"}, req.Header["Session"])
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -201,8 +204,11 @@ func TestClientAuth(t *testing.T) {
|
|||||||
err = v.ValidateRequest(req)
|
err = v.ValidateRequest(req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -266,8 +272,11 @@ func TestClientDescribeCharset(t *testing.T) {
|
|||||||
require.Equal(t, base.Describe, req.Method)
|
require.Equal(t, base.Describe, req.Method)
|
||||||
require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream"), req.URL)
|
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)
|
track1 := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
byts, _ = base.Response{
|
byts, _ = base.Response{
|
||||||
StatusCode: base.StatusOK,
|
StatusCode: base.StatusOK,
|
||||||
|
@@ -34,9 +34,14 @@ func main() {
|
|||||||
log.Println("stream connected")
|
log.Println("stream connected")
|
||||||
|
|
||||||
// create an AAC track
|
// create an AAC track
|
||||||
track, err := gortsplib.NewTrackAAC(96, 2, 48000, 2, nil, 13, 3, 3)
|
track := &gortsplib.TrackAAC{
|
||||||
if err != nil {
|
PayloadType: 96,
|
||||||
panic(err)
|
Type: 2,
|
||||||
|
SampleRate: 48000,
|
||||||
|
ChannelCount: 2,
|
||||||
|
SizeLength: 13,
|
||||||
|
IndexLength: 3,
|
||||||
|
IndexDeltaLength: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to the server and start publishing the track
|
// connect to the server and start publishing the track
|
||||||
|
@@ -35,9 +35,8 @@ func main() {
|
|||||||
log.Println("stream connected")
|
log.Println("stream connected")
|
||||||
|
|
||||||
// create an H264 track
|
// create an H264 track
|
||||||
track, err := gortsplib.NewTrackH264(96, nil, nil, nil)
|
track := &gortsplib.TrackH264{
|
||||||
if err != nil {
|
PayloadType: 96,
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to the server and start publishing the track
|
// connect to the server and start publishing the track
|
||||||
|
@@ -36,9 +36,8 @@ func main() {
|
|||||||
log.Println("stream connected")
|
log.Println("stream connected")
|
||||||
|
|
||||||
// create an H264 track
|
// create an H264 track
|
||||||
track, err := gortsplib.NewTrackH264(96, nil, nil, nil)
|
track := &gortsplib.TrackH264{
|
||||||
if err != nil {
|
PayloadType: 96,
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client allows to set additional client options
|
// Client allows to set additional client options
|
||||||
|
@@ -34,7 +34,11 @@ func main() {
|
|||||||
log.Println("stream connected")
|
log.Println("stream connected")
|
||||||
|
|
||||||
// create an Opus track
|
// create an Opus track
|
||||||
track := gortsplib.NewTrackOpus(96, 48000, 2)
|
track := &gortsplib.TrackOpus{
|
||||||
|
PayloadType: 96,
|
||||||
|
SampleRate: 48000,
|
||||||
|
ChannelCount: 2,
|
||||||
|
}
|
||||||
|
|
||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
|
@@ -37,9 +37,8 @@ func main() {
|
|||||||
log.Println("stream connected")
|
log.Println("stream connected")
|
||||||
|
|
||||||
// create an H264 track
|
// create an H264 track
|
||||||
track, err := gortsplib.NewTrackH264(96, nil, nil, nil)
|
track := &gortsplib.TrackH264{
|
||||||
if err != nil {
|
PayloadType: 96,
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to the server and start publishing the track
|
// connect to the server and start publishing the track
|
||||||
|
@@ -34,7 +34,7 @@ func main() {
|
|||||||
log.Println("stream connected")
|
log.Println("stream connected")
|
||||||
|
|
||||||
// create a PCMU track
|
// create a PCMU track
|
||||||
track := gortsplib.NewTrackPCMU()
|
track := &gortsplib.TrackPCMU{}
|
||||||
|
|
||||||
c := gortsplib.Client{}
|
c := gortsplib.Client{}
|
||||||
|
|
||||||
|
@@ -50,10 +50,10 @@ func main() {
|
|||||||
|
|
||||||
// setup decoder
|
// setup decoder
|
||||||
dec := &rtpaac.Decoder{
|
dec := &rtpaac.Decoder{
|
||||||
SampleRate: aacTrack.ClockRate(),
|
SampleRate: aacTrack.SampleRate,
|
||||||
SizeLength: aacTrack.SizeLength(),
|
SizeLength: aacTrack.SizeLength,
|
||||||
IndexLength: aacTrack.IndexLength(),
|
IndexLength: aacTrack.IndexLength,
|
||||||
IndexDeltaLength: aacTrack.IndexDeltaLength(),
|
IndexDeltaLength: aacTrack.IndexDeltaLength,
|
||||||
}
|
}
|
||||||
dec.Init()
|
dec.Init()
|
||||||
|
|
||||||
|
@@ -81,11 +81,13 @@ func main() {
|
|||||||
defer h264dec.close()
|
defer h264dec.close()
|
||||||
|
|
||||||
// if present, send SPS and PPS from the SDP to the decoder
|
// if present, send SPS and PPS from the SDP to the decoder
|
||||||
if h264track.SPS() != nil {
|
sps := h264track.SafeSPS()
|
||||||
h264dec.decode(h264track.SPS())
|
if sps != nil {
|
||||||
|
h264dec.decode(sps)
|
||||||
}
|
}
|
||||||
if h264track.PPS() != nil {
|
pps := h264track.SafePPS()
|
||||||
h264dec.decode(h264track.PPS())
|
if pps != nil {
|
||||||
|
h264dec.decode(pps)
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when a RTP packet arrives
|
// called when a RTP packet arrives
|
||||||
|
@@ -46,7 +46,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup H264->MPEGTS encoder
|
// setup H264->MPEGTS encoder
|
||||||
enc, err := newMPEGTSEncoder(h264track.SPS(), h264track.PPS())
|
enc, err := newMPEGTSEncoder(h264track.SafeSPS(), h264track.SafePPS())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@@ -58,11 +58,13 @@ func main() {
|
|||||||
defer h264dec.close()
|
defer h264dec.close()
|
||||||
|
|
||||||
// if present, send SPS and PPS from the SDP to the decoder
|
// if present, send SPS and PPS from the SDP to the decoder
|
||||||
if h264track.SPS() != nil {
|
sps := h264track.SafeSPS()
|
||||||
h264dec.decode(h264track.SPS())
|
if sps != nil {
|
||||||
|
h264dec.decode(sps)
|
||||||
}
|
}
|
||||||
if h264track.PPS() != nil {
|
pps := h264track.SafePPS()
|
||||||
h264dec.decode(h264track.PPS())
|
if pps != nil {
|
||||||
|
h264dec.decode(pps)
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when a RTP packet arrives
|
// called when a RTP packet arrives
|
||||||
|
@@ -25,8 +25,11 @@ func invalidURLAnnounceReq(t *testing.T, control string) base.Request {
|
|||||||
"Content-Type": base.HeaderValue{"application/sdp"},
|
"Content-Type": base.HeaderValue{"application/sdp"},
|
||||||
},
|
},
|
||||||
Body: func() []byte {
|
Body: func() []byte {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
track.SetControl(control)
|
track.SetControl(control)
|
||||||
|
|
||||||
sout := &psdp.SessionDescription{
|
sout := &psdp.SessionDescription{
|
||||||
@@ -227,9 +230,11 @@ func TestServerPublishSetupPath(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
track.SetControl(ca.control)
|
track.SetControl(ca.control)
|
||||||
|
|
||||||
sout := &psdp.SessionDescription{
|
sout := &psdp.SessionDescription{
|
||||||
@@ -320,8 +325,11 @@ func TestServerPublishErrorSetupDifferentPaths(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -397,8 +405,11 @@ func TestServerPublishErrorSetupTrackTwice(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -495,11 +506,17 @@ func TestServerPublishErrorRecordPartialTracks(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track1 := &TrackH264{
|
||||||
require.NoError(t, err)
|
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)
|
track2 := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track1, track2}
|
tracks := Tracks{track1, track2}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -646,8 +663,11 @@ func TestServerPublish(t *testing.T) {
|
|||||||
|
|
||||||
<-connOpened
|
<-connOpened
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -847,8 +867,11 @@ func TestServerPublishErrorInvalidProtocol(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -950,8 +973,11 @@ func TestServerPublishRTCPReport(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1124,8 +1150,11 @@ func TestServerPublishTimeout(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1250,8 +1279,11 @@ func TestServerPublishWithoutTeardown(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -1368,8 +1400,11 @@ func TestServerPublishUDPChangeConn(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
|
@@ -92,8 +92,11 @@ func TestServerReadSetupPath(t *testing.T) {
|
|||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(ca.name, func(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)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track, track, track, track, track})
|
stream := NewServerStream(Tracks{track, track, track, track, track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -111,7 +114,7 @@ func TestServerReadSetupPath(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -156,8 +159,11 @@ func TestServerReadSetupErrors(t *testing.T) {
|
|||||||
t.Run(ca, func(t *testing.T) {
|
t.Run(ca, func(t *testing.T) {
|
||||||
connClosed := make(chan struct{})
|
connClosed := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
if ca == "closed stream" {
|
if ca == "closed stream" {
|
||||||
@@ -190,7 +196,7 @@ func TestServerReadSetupErrors(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -288,8 +294,11 @@ func TestServerRead(t *testing.T) {
|
|||||||
sessionClosed := make(chan struct{})
|
sessionClosed := make(chan struct{})
|
||||||
framesReceived := make(chan struct{})
|
framesReceived := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -372,7 +381,7 @@ func TestServerRead(t *testing.T) {
|
|||||||
s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
|
s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -628,8 +637,11 @@ func TestServerRead(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerReadRTCPReport(t *testing.T) {
|
func TestServerReadRTCPReport(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -653,7 +665,7 @@ func TestServerReadRTCPReport(t *testing.T) {
|
|||||||
UDPRTCPAddress: "127.0.0.1:8001",
|
UDPRTCPAddress: "127.0.0.1:8001",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -738,8 +750,11 @@ func TestServerReadRTCPReport(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerReadVLCMulticast(t *testing.T) {
|
func TestServerReadVLCMulticast(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -760,7 +775,7 @@ func TestServerReadVLCMulticast(t *testing.T) {
|
|||||||
MulticastRTCPPort: 8001,
|
MulticastRTCPPort: 8001,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -790,8 +805,11 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) {
|
|||||||
writerDone := make(chan struct{})
|
writerDone := make(chan struct{})
|
||||||
writerTerminate := make(chan struct{})
|
writerTerminate := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -836,7 +854,7 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -888,8 +906,11 @@ func TestServerReadTCPResponseBeforeFrames(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerReadPlayPlay(t *testing.T) {
|
func TestServerReadPlayPlay(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -912,7 +933,7 @@ func TestServerReadPlayPlay(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -975,8 +996,11 @@ func TestServerReadPlayPausePlay(t *testing.T) {
|
|||||||
writerDone := make(chan struct{})
|
writerDone := make(chan struct{})
|
||||||
writerTerminate := make(chan struct{})
|
writerTerminate := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1025,7 +1049,7 @@ func TestServerReadPlayPausePlay(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1098,8 +1122,11 @@ func TestServerReadPlayPausePause(t *testing.T) {
|
|||||||
writerDone := make(chan struct{})
|
writerDone := make(chan struct{})
|
||||||
writerTerminate := make(chan struct{})
|
writerTerminate := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1145,7 +1172,7 @@ func TestServerReadPlayPausePause(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1231,8 +1258,11 @@ func TestServerReadTimeout(t *testing.T) {
|
|||||||
t.Run(transport, func(t *testing.T) {
|
t.Run(transport, func(t *testing.T) {
|
||||||
sessionClosed := make(chan struct{})
|
sessionClosed := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1274,7 +1304,7 @@ func TestServerReadTimeout(t *testing.T) {
|
|||||||
s.MulticastRTCPPort = 8001
|
s.MulticastRTCPPort = 8001
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1343,8 +1373,11 @@ func TestServerReadWithoutTeardown(t *testing.T) {
|
|||||||
connClosed := make(chan struct{})
|
connClosed := make(chan struct{})
|
||||||
sessionClosed := make(chan struct{})
|
sessionClosed := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1383,7 +1416,7 @@ func TestServerReadWithoutTeardown(t *testing.T) {
|
|||||||
s.UDPRTCPAddress = "127.0.0.1:8001"
|
s.UDPRTCPAddress = "127.0.0.1:8001"
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1446,8 +1479,11 @@ func TestServerReadWithoutTeardown(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerReadUDPChangeConn(t *testing.T) {
|
func TestServerReadUDPChangeConn(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1475,7 +1511,7 @@ func TestServerReadUDPChangeConn(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1549,11 +1585,17 @@ func TestServerReadUDPChangeConn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerReadPartialTracks(t *testing.T) {
|
func TestServerReadPartialTracks(t *testing.T) {
|
||||||
track1, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track1 := &TrackH264{
|
||||||
require.NoError(t, err)
|
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)
|
track2 := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track1, track2})
|
stream := NewServerStream(Tracks{track1, track2})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1580,7 +1622,7 @@ func TestServerReadPartialTracks(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1725,8 +1767,11 @@ func TestServerReadAdditionalInfos(t *testing.T) {
|
|||||||
return &ri, ssrcs
|
return &ri, ssrcs
|
||||||
}
|
}
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track, track})
|
stream := NewServerStream(Tracks{track, track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1747,7 +1792,7 @@ func TestServerReadAdditionalInfos(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -1836,8 +1881,11 @@ func TestServerReadAdditionalInfos(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerReadErrorUDPSamePorts(t *testing.T) {
|
func TestServerReadErrorUDPSamePorts(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -1860,7 +1908,7 @@ func TestServerReadErrorUDPSamePorts(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
|
@@ -351,8 +351,11 @@ func TestServerErrorInvalidMethod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
|
func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -378,7 +381,7 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -454,8 +457,11 @@ func TestServerErrorTCPTwoConnOneSession(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServerErrorTCPOneConnTwoSessions(t *testing.T) {
|
func TestServerErrorTCPOneConnTwoSessions(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -481,7 +487,7 @@ func TestServerErrorTCPOneConnTwoSessions(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -727,8 +733,11 @@ func TestServerSessionAutoClose(t *testing.T) {
|
|||||||
t.Run(ca, func(t *testing.T) {
|
t.Run(ca, func(t *testing.T) {
|
||||||
sessionClosed := make(chan struct{})
|
sessionClosed := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -753,7 +762,7 @@ func TestServerSessionAutoClose(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -802,8 +811,11 @@ func TestServerErrorInvalidPath(t *testing.T) {
|
|||||||
t.Run(string(method), func(t *testing.T) {
|
t.Run(string(method), func(t *testing.T) {
|
||||||
connClosed := make(chan struct{})
|
connClosed := make(chan struct{})
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
stream := NewServerStream(Tracks{track})
|
stream := NewServerStream(Tracks{track})
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
@@ -833,7 +845,7 @@ func TestServerErrorInvalidPath(t *testing.T) {
|
|||||||
RTSPAddress: "localhost:8554",
|
RTSPAddress: "localhost:8554",
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Start()
|
err := s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@@ -845,8 +857,11 @@ func TestServerErrorInvalidPath(t *testing.T) {
|
|||||||
sxID := ""
|
sxID := ""
|
||||||
|
|
||||||
if method == base.Record {
|
if method == base.Record {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
tracks := Tracks{track}
|
tracks := Tracks{track}
|
||||||
tracks.setControls()
|
tracks.setControls()
|
||||||
@@ -961,8 +976,11 @@ func TestServerAuth(t *testing.T) {
|
|||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
|
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil)
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
PPS: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
}
|
||||||
|
|
||||||
req := base.Request{
|
req := base.Request{
|
||||||
Method: base.Announce,
|
Method: base.Announce,
|
||||||
|
171
track_aac.go
171
track_aac.go
@@ -13,49 +13,16 @@ import (
|
|||||||
|
|
||||||
// TrackAAC is an AAC track.
|
// TrackAAC is an AAC track.
|
||||||
type TrackAAC struct {
|
type TrackAAC struct {
|
||||||
|
PayloadType uint8
|
||||||
|
Type int
|
||||||
|
SampleRate int
|
||||||
|
ChannelCount int
|
||||||
|
AOTSpecificConfig []byte
|
||||||
|
SizeLength int
|
||||||
|
IndexLength int
|
||||||
|
IndexDeltaLength int
|
||||||
|
|
||||||
trackBase
|
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(
|
func newTrackAACFromMediaDescription(
|
||||||
@@ -73,13 +40,15 @@ func newTrackAACFromMediaDescription(
|
|||||||
return nil, fmt.Errorf("invalid fmtp (%v)", v)
|
return nil, fmt.Errorf("invalid fmtp (%v)", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
track := &TrackAAC{
|
t := &TrackAAC{
|
||||||
|
PayloadType: payloadType,
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: control,
|
control: control,
|
||||||
},
|
},
|
||||||
payloadType: payloadType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configFound := false
|
||||||
|
|
||||||
for _, kv := range strings.Split(tmp[1], ";") {
|
for _, kv := range strings.Split(tmp[1], ";") {
|
||||||
kv = strings.Trim(kv, " ")
|
kv = strings.Trim(kv, " ")
|
||||||
|
|
||||||
@@ -99,108 +68,84 @@ func newTrackAACFromMediaDescription(
|
|||||||
return nil, fmt.Errorf("invalid AAC config (%v)", tmp[1])
|
return nil, fmt.Errorf("invalid AAC config (%v)", tmp[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
var mpegConf aac.MPEG4AudioConfig
|
var MPEGConf aac.MPEG4AudioConfig
|
||||||
err = mpegConf.Decode(enc)
|
err = MPEGConf.Decode(enc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid AAC config (%v)", tmp[1])
|
return nil, fmt.Errorf("invalid AAC config (%v)", tmp[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-encode the conf to normalize it
|
t.Type = int(MPEGConf.Type)
|
||||||
enc, _ = mpegConf.Encode()
|
t.SampleRate = MPEGConf.SampleRate
|
||||||
|
t.ChannelCount = MPEGConf.ChannelCount
|
||||||
track.typ = int(mpegConf.Type)
|
t.AOTSpecificConfig = MPEGConf.AOTSpecificConfig
|
||||||
track.sampleRate = mpegConf.SampleRate
|
configFound = true
|
||||||
track.channelCount = mpegConf.ChannelCount
|
|
||||||
track.aotSpecificConfig = mpegConf.AOTSpecificConfig
|
|
||||||
track.mpegConf = enc
|
|
||||||
|
|
||||||
case "sizelength":
|
case "sizelength":
|
||||||
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
||||||
if err != nil {
|
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":
|
case "indexlength":
|
||||||
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
||||||
if err != nil {
|
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":
|
case "indexdeltalength":
|
||||||
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
||||||
if err != nil {
|
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)
|
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 nil, fmt.Errorf("sizelength is missing (%v)", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return track, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClockRate returns the track clock rate.
|
// ClockRate returns the track clock rate.
|
||||||
func (t *TrackAAC) ClockRate() int {
|
func (t *TrackAAC) ClockRate() int {
|
||||||
return t.sampleRate
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrackAAC) clone() Track {
|
func (t *TrackAAC) clone() Track {
|
||||||
return &TrackAAC{
|
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,
|
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.
|
// MediaDescription returns the track media description in SDP format.
|
||||||
func (t *TrackAAC) MediaDescription() *psdp.MediaDescription {
|
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{
|
return &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
@@ -211,32 +156,32 @@ func (t *TrackAAC) MediaDescription() *psdp.MediaDescription {
|
|||||||
Attributes: []psdp.Attribute{
|
Attributes: []psdp.Attribute{
|
||||||
{
|
{
|
||||||
Key: "rtpmap",
|
Key: "rtpmap",
|
||||||
Value: typ + " mpeg4-generic/" + strconv.FormatInt(int64(t.sampleRate), 10) +
|
Value: typ + " mpeg4-generic/" + strconv.FormatInt(int64(t.SampleRate), 10) +
|
||||||
"/" + strconv.FormatInt(int64(t.channelCount), 10),
|
"/" + strconv.FormatInt(int64(t.ChannelCount), 10),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: "fmtp",
|
Key: "fmtp",
|
||||||
Value: typ + " profile-level-id=1; " +
|
Value: typ + " profile-level-id=1; " +
|
||||||
"mode=AAC-hbr; " +
|
"mode=AAC-hbr; " +
|
||||||
func() string {
|
func() string {
|
||||||
if t.sizeLength > 0 {
|
if t.SizeLength > 0 {
|
||||||
return fmt.Sprintf("sizelength=%d; ", t.sizeLength)
|
return fmt.Sprintf("sizelength=%d; ", t.SizeLength)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}() +
|
}() +
|
||||||
func() string {
|
func() string {
|
||||||
if t.indexLength > 0 {
|
if t.IndexLength > 0 {
|
||||||
return fmt.Sprintf("indexlength=%d; ", t.indexLength)
|
return fmt.Sprintf("indexlength=%d; ", t.IndexLength)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}() +
|
}() +
|
||||||
func() string {
|
func() string {
|
||||||
if t.indexDeltaLength > 0 {
|
if t.IndexDeltaLength > 0 {
|
||||||
return fmt.Sprintf("indexdeltalength=%d; ", t.indexDeltaLength)
|
return fmt.Sprintf("indexdeltalength=%d; ", t.IndexDeltaLength)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}() +
|
}() +
|
||||||
"config=" + hex.EncodeToString(t.mpegConf),
|
"config=" + hex.EncodeToString(mpegConf),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: "control",
|
Key: "control",
|
||||||
|
@@ -7,27 +7,17 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func TestTrackAACClone(t *testing.T) {
|
||||||
track, err := NewTrackAAC(96, 2, 48000, 2, []byte{0x01, 0x02}, 13, 3, 3)
|
track := &TrackAAC{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
Type: 2,
|
||||||
|
SampleRate: 48000,
|
||||||
|
ChannelCount: 2,
|
||||||
|
AOTSpecificConfig: []byte{0x01, 0x02},
|
||||||
|
SizeLength: 13,
|
||||||
|
IndexLength: 3,
|
||||||
|
IndexDeltaLength: 3,
|
||||||
|
}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -35,8 +25,15 @@ func TestTrackAACClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackAACMediaDescription(t *testing.T) {
|
func TestTrackAACMediaDescription(t *testing.T) {
|
||||||
track, err := NewTrackAAC(96, 2, 48000, 2, nil, 13, 3, 3)
|
track := &TrackAAC{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
Type: 2,
|
||||||
|
SampleRate: 48000,
|
||||||
|
ChannelCount: 2,
|
||||||
|
SizeLength: 13,
|
||||||
|
IndexLength: 3,
|
||||||
|
IndexDeltaLength: 3,
|
||||||
|
}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -61,28 +61,12 @@ func trackGenericGetClockRate(formats []string, rtpmap string) (int, error) {
|
|||||||
|
|
||||||
// TrackGeneric is a generic track.
|
// TrackGeneric is a generic track.
|
||||||
type TrackGeneric struct {
|
type TrackGeneric struct {
|
||||||
|
Media string
|
||||||
|
Formats []string
|
||||||
|
RTPMap string
|
||||||
|
FMTP string
|
||||||
|
|
||||||
trackBase
|
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(
|
func newTrackGenericFromMediaDescription(
|
||||||
@@ -98,7 +82,7 @@ func newTrackGenericFromMediaDescription(
|
|||||||
return ""
|
return ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
clockRate, err := trackGenericGetClockRate(md.MediaName.Formats, rtpmap)
|
_, err := trackGenericGetClockRate(md.MediaName.Formats, rtpmap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to get clock rate: %s", err)
|
return nil, fmt.Errorf("unable to get clock rate: %s", err)
|
||||||
}
|
}
|
||||||
@@ -113,30 +97,29 @@ func newTrackGenericFromMediaDescription(
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
return &TrackGeneric{
|
return &TrackGeneric{
|
||||||
|
Media: md.MediaName.Media,
|
||||||
|
Formats: md.MediaName.Formats,
|
||||||
|
RTPMap: rtpmap,
|
||||||
|
FMTP: fmtp,
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: control,
|
control: control,
|
||||||
},
|
},
|
||||||
clockRate: clockRate,
|
|
||||||
media: md.MediaName.Media,
|
|
||||||
formats: md.MediaName.Formats,
|
|
||||||
rtpmap: rtpmap,
|
|
||||||
fmtp: fmtp,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClockRate returns the track clock rate.
|
// ClockRate returns the track clock rate.
|
||||||
func (t *TrackGeneric) ClockRate() int {
|
func (t *TrackGeneric) ClockRate() int {
|
||||||
return t.clockRate
|
clockRate, _ := trackGenericGetClockRate(t.Formats, t.RTPMap)
|
||||||
|
return clockRate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrackGeneric) clone() Track {
|
func (t *TrackGeneric) clone() Track {
|
||||||
return &TrackGeneric{
|
return &TrackGeneric{
|
||||||
|
Media: t.Media,
|
||||||
|
Formats: t.Formats,
|
||||||
|
RTPMap: t.RTPMap,
|
||||||
|
FMTP: t.FMTP,
|
||||||
trackBase: t.trackBase,
|
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 {
|
func (t *TrackGeneric) MediaDescription() *psdp.MediaDescription {
|
||||||
return &psdp.MediaDescription{
|
return &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
Media: t.media,
|
Media: t.Media,
|
||||||
Protos: []string{"RTP", "AVP"},
|
Protos: []string{"RTP", "AVP"},
|
||||||
Formats: t.formats,
|
Formats: t.Formats,
|
||||||
},
|
},
|
||||||
Attributes: func() []psdp.Attribute {
|
Attributes: func() []psdp.Attribute {
|
||||||
var ret []psdp.Attribute
|
var ret []psdp.Attribute
|
||||||
|
|
||||||
if t.rtpmap != "" {
|
if t.RTPMap != "" {
|
||||||
ret = append(ret, psdp.Attribute{
|
ret = append(ret, psdp.Attribute{
|
||||||
Key: "rtpmap",
|
Key: "rtpmap",
|
||||||
Value: t.rtpmap,
|
Value: t.RTPMap,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.fmtp != "" {
|
if t.FMTP != "" {
|
||||||
ret = append(ret, psdp.Attribute{
|
ret = append(ret, psdp.Attribute{
|
||||||
Key: "fmtp",
|
Key: "fmtp",
|
||||||
Value: t.fmtp,
|
Value: t.FMTP,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,38 +7,14 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func TestTrackGenericClone(t *testing.T) {
|
||||||
track, err := NewTrackGeneric(
|
track := &TrackGeneric{
|
||||||
"video",
|
Media: "video",
|
||||||
[]string{"100", "101"},
|
Formats: []string{"100", "101"},
|
||||||
"98 H265/90000",
|
RTPMap: "98 H265/90000",
|
||||||
"98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; "+
|
FMTP: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " +
|
||||||
"sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=",
|
"sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=",
|
||||||
)
|
}
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -46,14 +22,13 @@ func TestTrackGenericClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackGenericMediaDescription(t *testing.T) {
|
func TestTrackGenericMediaDescription(t *testing.T) {
|
||||||
track, err := NewTrackGeneric(
|
track := &TrackGeneric{
|
||||||
"video",
|
Media: "video",
|
||||||
[]string{"100", "101"},
|
Formats: []string{"100", "101"},
|
||||||
"98 H265/90000",
|
RTPMap: "98 H265/90000",
|
||||||
"98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; "+
|
FMTP: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " +
|
||||||
"sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=",
|
"sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=",
|
||||||
)
|
}
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
Media: "video",
|
Media: "video",
|
||||||
|
@@ -13,22 +13,13 @@ import (
|
|||||||
|
|
||||||
// TrackH264 is a H264 track.
|
// TrackH264 is a H264 track.
|
||||||
type TrackH264 struct {
|
type TrackH264 struct {
|
||||||
trackBase
|
PayloadType uint8
|
||||||
payloadType uint8
|
SPS []byte
|
||||||
sps []byte
|
PPS []byte
|
||||||
pps []byte
|
Extradata []byte
|
||||||
extradata []byte
|
|
||||||
mutex sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTrackH264 allocates a TrackH264.
|
trackBase
|
||||||
func NewTrackH264(payloadType uint8, sps []byte, pps []byte, extradata []byte) (*TrackH264, error) {
|
mutex sync.RWMutex
|
||||||
return &TrackH264{
|
|
||||||
payloadType: payloadType,
|
|
||||||
sps: sps,
|
|
||||||
pps: pps,
|
|
||||||
extradata: extradata,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTrackH264FromMediaDescription(
|
func newTrackH264FromMediaDescription(
|
||||||
@@ -37,10 +28,10 @@ func newTrackH264FromMediaDescription(
|
|||||||
md *psdp.MediaDescription,
|
md *psdp.MediaDescription,
|
||||||
) (*TrackH264, error) {
|
) (*TrackH264, error) {
|
||||||
t := &TrackH264{
|
t := &TrackH264{
|
||||||
|
PayloadType: payloadType,
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: control,
|
control: control,
|
||||||
},
|
},
|
||||||
payloadType: payloadType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.fillParamsFromMediaDescription(md)
|
t.fillParamsFromMediaDescription(md)
|
||||||
@@ -96,9 +87,9 @@ func (t *TrackH264) fillParamsFromMediaDescription(md *psdp.MediaDescription) er
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.sps = sps
|
t.SPS = sps
|
||||||
t.pps = pps
|
t.PPS = pps
|
||||||
t.extradata = extradata
|
t.Extradata = extradata
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,45 +104,40 @@ func (t *TrackH264) ClockRate() int {
|
|||||||
|
|
||||||
func (t *TrackH264) clone() Track {
|
func (t *TrackH264) clone() Track {
|
||||||
return &TrackH264{
|
return &TrackH264{
|
||||||
|
PayloadType: t.PayloadType,
|
||||||
|
SPS: t.SPS,
|
||||||
|
PPS: t.PPS,
|
||||||
|
Extradata: t.Extradata,
|
||||||
trackBase: t.trackBase,
|
trackBase: t.trackBase,
|
||||||
payloadType: t.payloadType,
|
|
||||||
sps: t.sps,
|
|
||||||
pps: t.pps,
|
|
||||||
extradata: t.extradata,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPS returns the track SPS.
|
// SafeSPS returns the track SPS.
|
||||||
func (t *TrackH264) SPS() []byte {
|
func (t *TrackH264) SafeSPS() []byte {
|
||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
return t.sps
|
return t.SPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// PPS returns the track PPS.
|
// SafePPS returns the track PPS.
|
||||||
func (t *TrackH264) PPS() []byte {
|
func (t *TrackH264) SafePPS() []byte {
|
||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
return t.pps
|
return t.PPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtraData returns the track extra data.
|
// SafeSetSPS sets the track SPS.
|
||||||
func (t *TrackH264) ExtraData() []byte {
|
func (t *TrackH264) SafeSetSPS(v []byte) {
|
||||||
return t.extradata
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSPS sets the track SPS.
|
|
||||||
func (t *TrackH264) SetSPS(v []byte) {
|
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.sps = v
|
t.SPS = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPPS sets the track PPS.
|
// SafeSetPPS sets the track PPS.
|
||||||
func (t *TrackH264) SetPPS(v []byte) {
|
func (t *TrackH264) SafeSetPPS(v []byte) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.pps = v
|
t.PPS = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// MediaDescription returns the track media description in SDP format.
|
// MediaDescription returns the track media description in SDP format.
|
||||||
@@ -159,24 +145,24 @@ func (t *TrackH264) MediaDescription() *psdp.MediaDescription {
|
|||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
|
|
||||||
typ := strconv.FormatInt(int64(t.payloadType), 10)
|
typ := strconv.FormatInt(int64(t.PayloadType), 10)
|
||||||
|
|
||||||
fmtp := typ + " packetization-mode=1"
|
fmtp := typ + " packetization-mode=1"
|
||||||
|
|
||||||
var tmp []string
|
var tmp []string
|
||||||
if t.sps != nil {
|
if t.SPS != nil {
|
||||||
tmp = append(tmp, base64.StdEncoding.EncodeToString(t.sps))
|
tmp = append(tmp, base64.StdEncoding.EncodeToString(t.SPS))
|
||||||
}
|
}
|
||||||
if t.pps != nil {
|
if t.PPS != nil {
|
||||||
tmp = append(tmp, base64.StdEncoding.EncodeToString(t.pps))
|
tmp = append(tmp, base64.StdEncoding.EncodeToString(t.PPS))
|
||||||
}
|
}
|
||||||
if t.extradata != nil {
|
if t.Extradata != nil {
|
||||||
tmp = append(tmp, base64.StdEncoding.EncodeToString(t.extradata))
|
tmp = append(tmp, base64.StdEncoding.EncodeToString(t.Extradata))
|
||||||
}
|
}
|
||||||
fmtp += "; sprop-parameter-sets=" + strings.Join(tmp, ",")
|
fmtp += "; sprop-parameter-sets=" + strings.Join(tmp, ",")
|
||||||
|
|
||||||
if len(t.sps) >= 4 {
|
if len(t.SPS) >= 4 {
|
||||||
fmtp += "; profile-level-id=" + strings.ToUpper(hex.EncodeToString(t.sps[1:4]))
|
fmtp += "; profile-level-id=" + strings.ToUpper(hex.EncodeToString(t.SPS[1:4]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &psdp.MediaDescription{
|
return &psdp.MediaDescription{
|
||||||
|
@@ -165,19 +165,30 @@ func TestTrackH264GetSPSPPSErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackH264New(t *testing.T) {
|
func TestTrackH264Params(t *testing.T) {
|
||||||
track, err := NewTrackH264(96,
|
track := &TrackH264{
|
||||||
[]byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06})
|
PayloadType: 96,
|
||||||
require.NoError(t, err)
|
SPS: []byte{0x01, 0x02},
|
||||||
|
PPS: []byte{0x03, 0x04},
|
||||||
|
Extradata: []byte{0x05, 0x06},
|
||||||
|
}
|
||||||
require.Equal(t, "", track.GetControl())
|
require.Equal(t, "", track.GetControl())
|
||||||
require.Equal(t, []byte{0x01, 0x02}, track.SPS())
|
require.Equal(t, []byte{0x01, 0x02}, track.SafeSPS())
|
||||||
require.Equal(t, []byte{0x03, 0x04}, track.PPS())
|
require.Equal(t, []byte{0x03, 0x04}, track.SafePPS())
|
||||||
require.Equal(t, []byte{0x05, 0x06}, track.ExtraData())
|
|
||||||
|
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) {
|
func TestTrackH264Clone(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06})
|
track := &TrackH264{
|
||||||
require.NoError(t, err)
|
PayloadType: 96,
|
||||||
|
SPS: []byte{0x01, 0x02},
|
||||||
|
PPS: []byte{0x03, 0x04},
|
||||||
|
Extradata: []byte{0x05, 0x06},
|
||||||
|
}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -185,19 +196,20 @@ func TestTrackH264Clone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackH264MediaDescription(t *testing.T) {
|
func TestTrackH264MediaDescription(t *testing.T) {
|
||||||
track, err := NewTrackH264(96,
|
track := &TrackH264{
|
||||||
[]byte{
|
PayloadType: 96,
|
||||||
|
SPS: []byte{
|
||||||
0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0,
|
0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0,
|
||||||
0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
|
0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
|
||||||
0x00, 0x03, 0x00, 0x3d, 0x08,
|
0x00, 0x03, 0x00, 0x3d, 0x08,
|
||||||
},
|
},
|
||||||
[]byte{
|
PPS: []byte{
|
||||||
0x68, 0xee, 0x3c, 0x80,
|
0x68, 0xee, 0x3c, 0x80,
|
||||||
},
|
},
|
||||||
[]byte{
|
Extradata: []byte{
|
||||||
0x01, 0x02,
|
0x01, 0x02,
|
||||||
})
|
},
|
||||||
require.NoError(t, err)
|
}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -12,22 +12,13 @@ import (
|
|||||||
|
|
||||||
// TrackH265 is a H265 track.
|
// TrackH265 is a H265 track.
|
||||||
type TrackH265 struct {
|
type TrackH265 struct {
|
||||||
trackBase
|
PayloadType uint8
|
||||||
payloadType uint8
|
VPS []byte
|
||||||
vps []byte
|
SPS []byte
|
||||||
sps []byte
|
PPS []byte
|
||||||
pps []byte
|
|
||||||
mutex sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTrackH265 allocates a TrackH265.
|
trackBase
|
||||||
func NewTrackH265(payloadType uint8, vps []byte, sps []byte, pps []byte) *TrackH265 {
|
mutex sync.RWMutex
|
||||||
return &TrackH265{
|
|
||||||
payloadType: payloadType,
|
|
||||||
vps: vps,
|
|
||||||
sps: sps,
|
|
||||||
pps: pps,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTrackH265FromMediaDescription(
|
func newTrackH265FromMediaDescription(
|
||||||
@@ -36,10 +27,10 @@ func newTrackH265FromMediaDescription(
|
|||||||
md *psdp.MediaDescription,
|
md *psdp.MediaDescription,
|
||||||
) (*TrackH265, error) {
|
) (*TrackH265, error) {
|
||||||
t := &TrackH265{
|
t := &TrackH265{
|
||||||
|
PayloadType: payloadType,
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: control,
|
control: control,
|
||||||
},
|
},
|
||||||
payloadType: payloadType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.fillParamsFromMediaDescription(md)
|
t.fillParamsFromMediaDescription(md)
|
||||||
@@ -73,21 +64,21 @@ func (t *TrackH265) fillParamsFromMediaDescription(md *psdp.MediaDescription) er
|
|||||||
switch tmp[0] {
|
switch tmp[0] {
|
||||||
case "sprop-vps":
|
case "sprop-vps":
|
||||||
var err error
|
var err error
|
||||||
t.vps, err = base64.StdEncoding.DecodeString(tmp[1])
|
t.VPS, err = base64.StdEncoding.DecodeString(tmp[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid sprop-vps (%v)", v)
|
return fmt.Errorf("invalid sprop-vps (%v)", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "sprop-sps":
|
case "sprop-sps":
|
||||||
var err error
|
var err error
|
||||||
t.sps, err = base64.StdEncoding.DecodeString(tmp[1])
|
t.SPS, err = base64.StdEncoding.DecodeString(tmp[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid sprop-sps (%v)", v)
|
return fmt.Errorf("invalid sprop-sps (%v)", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "sprop-pps":
|
case "sprop-pps":
|
||||||
var err error
|
var err error
|
||||||
t.pps, err = base64.StdEncoding.DecodeString(tmp[1])
|
t.PPS, err = base64.StdEncoding.DecodeString(tmp[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid sprop-pps (%v)", v)
|
return fmt.Errorf("invalid sprop-pps (%v)", v)
|
||||||
}
|
}
|
||||||
@@ -104,54 +95,54 @@ func (t *TrackH265) ClockRate() int {
|
|||||||
|
|
||||||
func (t *TrackH265) clone() Track {
|
func (t *TrackH265) clone() Track {
|
||||||
return &TrackH265{
|
return &TrackH265{
|
||||||
|
PayloadType: t.PayloadType,
|
||||||
|
VPS: t.VPS,
|
||||||
|
SPS: t.SPS,
|
||||||
|
PPS: t.PPS,
|
||||||
trackBase: t.trackBase,
|
trackBase: t.trackBase,
|
||||||
payloadType: t.payloadType,
|
|
||||||
vps: t.vps,
|
|
||||||
sps: t.sps,
|
|
||||||
pps: t.pps,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VPS returns the track VPS.
|
// SafeVPS returns the track VPS.
|
||||||
func (t *TrackH265) VPS() []byte {
|
func (t *TrackH265) SafeVPS() []byte {
|
||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
return t.vps
|
return t.VPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPS returns the track SPS.
|
// SafeSPS returns the track SPS.
|
||||||
func (t *TrackH265) SPS() []byte {
|
func (t *TrackH265) SafeSPS() []byte {
|
||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
return t.sps
|
return t.SPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// PPS returns the track PPS.
|
// SafePPS returns the track PPS.
|
||||||
func (t *TrackH265) PPS() []byte {
|
func (t *TrackH265) SafePPS() []byte {
|
||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
return t.pps
|
return t.PPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVPS sets the track VPS.
|
// SafeSetVPS sets the track VPS.
|
||||||
func (t *TrackH265) SetVPS(v []byte) {
|
func (t *TrackH265) SafeSetVPS(v []byte) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.vps = v
|
t.VPS = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSPS sets the track SPS.
|
// SafeSetSPS sets the track SPS.
|
||||||
func (t *TrackH265) SetSPS(v []byte) {
|
func (t *TrackH265) SafeSetSPS(v []byte) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.sps = v
|
t.SPS = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPPS sets the track PPS.
|
// SafeSetPPS sets the track PPS.
|
||||||
func (t *TrackH265) SetPPS(v []byte) {
|
func (t *TrackH265) SafeSetPPS(v []byte) {
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
defer t.mutex.Unlock()
|
defer t.mutex.Unlock()
|
||||||
t.pps = v
|
t.PPS = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// MediaDescription returns the track media description in SDP format.
|
// MediaDescription returns the track media description in SDP format.
|
||||||
@@ -159,19 +150,19 @@ func (t *TrackH265) MediaDescription() *psdp.MediaDescription {
|
|||||||
t.mutex.RLock()
|
t.mutex.RLock()
|
||||||
defer t.mutex.RUnlock()
|
defer t.mutex.RUnlock()
|
||||||
|
|
||||||
typ := strconv.FormatInt(int64(t.payloadType), 10)
|
typ := strconv.FormatInt(int64(t.PayloadType), 10)
|
||||||
|
|
||||||
fmtp := typ
|
fmtp := typ
|
||||||
|
|
||||||
var tmp []string
|
var tmp []string
|
||||||
if t.vps != nil {
|
if t.VPS != nil {
|
||||||
tmp = append(tmp, "sprop-vps="+base64.StdEncoding.EncodeToString(t.vps))
|
tmp = append(tmp, "sprop-vps="+base64.StdEncoding.EncodeToString(t.VPS))
|
||||||
}
|
}
|
||||||
if t.sps != nil {
|
if t.SPS != nil {
|
||||||
tmp = append(tmp, "sprop-sps="+base64.StdEncoding.EncodeToString(t.sps))
|
tmp = append(tmp, "sprop-sps="+base64.StdEncoding.EncodeToString(t.SPS))
|
||||||
}
|
}
|
||||||
if t.pps != nil {
|
if t.PPS != nil {
|
||||||
tmp = append(tmp, "sprop-pps="+base64.StdEncoding.EncodeToString(t.pps))
|
tmp = append(tmp, "sprop-pps="+base64.StdEncoding.EncodeToString(t.PPS))
|
||||||
}
|
}
|
||||||
if tmp != nil {
|
if tmp != nil {
|
||||||
fmtp += " " + strings.Join(tmp, "; ")
|
fmtp += " " + strings.Join(tmp, "; ")
|
||||||
|
@@ -7,17 +7,33 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackH265New(t *testing.T) {
|
func TestTrackH265Params(t *testing.T) {
|
||||||
track := NewTrackH265(96,
|
track := &TrackH265{
|
||||||
[]byte{0x01, 0x02}, []byte{0x03, 0x04}, []byte{0x05, 0x06})
|
PayloadType: 96,
|
||||||
|
VPS: []byte{0x01, 0x02},
|
||||||
|
SPS: []byte{0x03, 0x04},
|
||||||
|
PPS: []byte{0x05, 0x06},
|
||||||
|
}
|
||||||
require.Equal(t, "", track.GetControl())
|
require.Equal(t, "", track.GetControl())
|
||||||
require.Equal(t, []byte{0x01, 0x02}, track.VPS())
|
require.Equal(t, []byte{0x01, 0x02}, track.SafeVPS())
|
||||||
require.Equal(t, []byte{0x03, 0x04}, track.SPS())
|
require.Equal(t, []byte{0x03, 0x04}, track.SafeSPS())
|
||||||
require.Equal(t, []byte{0x05, 0x06}, track.PPS())
|
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) {
|
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()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -25,7 +41,12 @@ func TestTrackH265Clone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackH265MediaDescription(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{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -9,11 +9,6 @@ type TrackJPEG struct {
|
|||||||
trackBase
|
trackBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrackJPEG allocates a TrackJPEG.
|
|
||||||
func NewTrackJPEG() *TrackJPEG {
|
|
||||||
return &TrackJPEG{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTrackJPEGFromMediaDescription(
|
func newTrackJPEGFromMediaDescription(
|
||||||
control string) (*TrackJPEG, error,
|
control string) (*TrackJPEG, error,
|
||||||
) {
|
) {
|
||||||
|
@@ -7,13 +7,8 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackJPEGNew(t *testing.T) {
|
|
||||||
track := NewTrackJPEG()
|
|
||||||
require.Equal(t, "", track.GetControl())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTrackJPEGClone(t *testing.T) {
|
func TestTrackJPEGClone(t *testing.T) {
|
||||||
track := NewTrackJPEG()
|
track := &TrackJPEG{}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -21,7 +16,7 @@ func TestTrackJPEGClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackJPEGMediaDescription(t *testing.T) {
|
func TestTrackJPEGMediaDescription(t *testing.T) {
|
||||||
track := NewTrackJPEG()
|
track := &TrackJPEG{}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -9,11 +9,6 @@ type TrackMpegAudio struct {
|
|||||||
trackBase
|
trackBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrackMpegAudio allocates a TrackMpegAudio.
|
|
||||||
func NewTrackMpegAudio() *TrackMpegAudio {
|
|
||||||
return &TrackMpegAudio{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTrackMpegAudioFromMediaDescription(
|
func newTrackMpegAudioFromMediaDescription(
|
||||||
control string) (*TrackMpegAudio, error,
|
control string) (*TrackMpegAudio, error,
|
||||||
) {
|
) {
|
||||||
|
@@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackMpegAudioNew(t *testing.T) {
|
func TestTrackMpegAudioNew(t *testing.T) {
|
||||||
track := NewTrackMpegAudio()
|
track := &TrackMpegAudio{}
|
||||||
require.Equal(t, "", track.GetControl())
|
require.Equal(t, "", track.GetControl())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackMpegAudioClone(t *testing.T) {
|
func TestTrackMpegAudioClone(t *testing.T) {
|
||||||
track := NewTrackMpegAudio()
|
track := &TrackMpegAudio{}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -21,7 +21,7 @@ func TestTrackMpegAudioClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackMpegAudioMediaDescription(t *testing.T) {
|
func TestTrackMpegAudioMediaDescription(t *testing.T) {
|
||||||
track := NewTrackMpegAudio()
|
track := &TrackMpegAudio{}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -9,11 +9,6 @@ type TrackMpegVideo struct {
|
|||||||
trackBase
|
trackBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrackMpegVideo allocates a TrackMpegVideo.
|
|
||||||
func NewTrackMpegVideo() *TrackMpegVideo {
|
|
||||||
return &TrackMpegVideo{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTrackMpegVideoFromMediaDescription(
|
func newTrackMpegVideoFromMediaDescription(
|
||||||
control string) (*TrackMpegVideo, error,
|
control string) (*TrackMpegVideo, error,
|
||||||
) {
|
) {
|
||||||
|
@@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackMpegVideoNew(t *testing.T) {
|
func TestTrackMpegVideoNew(t *testing.T) {
|
||||||
track := NewTrackMpegVideo()
|
track := &TrackMpegVideo{}
|
||||||
require.Equal(t, "", track.GetControl())
|
require.Equal(t, "", track.GetControl())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackMpegVideoClone(t *testing.T) {
|
func TestTrackMpegVideoClone(t *testing.T) {
|
||||||
track := NewTrackMpegVideo()
|
track := &TrackMpegVideo{}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -21,7 +21,7 @@ func TestTrackMpegVideoClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackMpegVideoMediaDescription(t *testing.T) {
|
func TestTrackMpegVideoMediaDescription(t *testing.T) {
|
||||||
track := NewTrackMpegVideo()
|
track := &TrackMpegVideo{}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -10,19 +10,11 @@ import (
|
|||||||
|
|
||||||
// TrackOpus is a Opus track.
|
// TrackOpus is a Opus track.
|
||||||
type TrackOpus struct {
|
type TrackOpus struct {
|
||||||
trackBase
|
PayloadType uint8
|
||||||
payloadType uint8
|
SampleRate int
|
||||||
sampleRate int
|
ChannelCount int
|
||||||
channelCount int
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTrackOpus allocates a TrackOpus.
|
trackBase
|
||||||
func NewTrackOpus(payloadType uint8, sampleRate int, channelCount int) *TrackOpus {
|
|
||||||
return &TrackOpus{
|
|
||||||
payloadType: payloadType,
|
|
||||||
sampleRate: sampleRate,
|
|
||||||
channelCount: channelCount,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTrackOpusFromMediaDescription(
|
func newTrackOpusFromMediaDescription(
|
||||||
@@ -47,37 +39,32 @@ func newTrackOpusFromMediaDescription(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &TrackOpus{
|
return &TrackOpus{
|
||||||
|
PayloadType: payloadType,
|
||||||
|
SampleRate: int(sampleRate),
|
||||||
|
ChannelCount: int(channelCount),
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: control,
|
control: control,
|
||||||
},
|
},
|
||||||
payloadType: payloadType,
|
|
||||||
sampleRate: int(sampleRate),
|
|
||||||
channelCount: int(channelCount),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClockRate returns the track clock rate.
|
// ClockRate returns the track clock rate.
|
||||||
func (t *TrackOpus) ClockRate() int {
|
func (t *TrackOpus) ClockRate() int {
|
||||||
return t.sampleRate
|
return t.SampleRate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrackOpus) clone() Track {
|
func (t *TrackOpus) clone() Track {
|
||||||
return &TrackOpus{
|
return &TrackOpus{
|
||||||
|
PayloadType: t.PayloadType,
|
||||||
|
SampleRate: t.SampleRate,
|
||||||
|
ChannelCount: t.ChannelCount,
|
||||||
trackBase: t.trackBase,
|
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.
|
// MediaDescription returns the track media description in SDP format.
|
||||||
func (t *TrackOpus) MediaDescription() *psdp.MediaDescription {
|
func (t *TrackOpus) MediaDescription() *psdp.MediaDescription {
|
||||||
typ := strconv.FormatInt(int64(t.payloadType), 10)
|
typ := strconv.FormatInt(int64(t.PayloadType), 10)
|
||||||
|
|
||||||
return &psdp.MediaDescription{
|
return &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
@@ -88,13 +75,13 @@ func (t *TrackOpus) MediaDescription() *psdp.MediaDescription {
|
|||||||
Attributes: []psdp.Attribute{
|
Attributes: []psdp.Attribute{
|
||||||
{
|
{
|
||||||
Key: "rtpmap",
|
Key: "rtpmap",
|
||||||
Value: typ + " opus/" + strconv.FormatInt(int64(t.sampleRate), 10) +
|
Value: typ + " opus/" + strconv.FormatInt(int64(t.SampleRate), 10) +
|
||||||
"/" + strconv.FormatInt(int64(t.channelCount), 10),
|
"/" + strconv.FormatInt(int64(t.ChannelCount), 10),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: "fmtp",
|
Key: "fmtp",
|
||||||
Value: typ + " sprop-stereo=" + func() string {
|
Value: typ + " sprop-stereo=" + func() string {
|
||||||
if t.channelCount == 2 {
|
if t.ChannelCount == 2 {
|
||||||
return "1"
|
return "1"
|
||||||
}
|
}
|
||||||
return "0"
|
return "0"
|
||||||
|
@@ -7,15 +7,12 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func TestTracOpusClone(t *testing.T) {
|
||||||
track := NewTrackOpus(96, 96000, 4)
|
track := &TrackOpus{
|
||||||
|
PayloadType: 96,
|
||||||
|
SampleRate: 48000,
|
||||||
|
ChannelCount: 2,
|
||||||
|
}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -23,7 +20,11 @@ func TestTracOpusClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackOpusMediaDescription(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{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -12,11 +12,6 @@ type TrackPCMA struct {
|
|||||||
trackBase
|
trackBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrackPCMA allocates a TrackPCMA.
|
|
||||||
func NewTrackPCMA() *TrackPCMA {
|
|
||||||
return &TrackPCMA{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTrackPCMAFromMediaDescription(
|
func newTrackPCMAFromMediaDescription(
|
||||||
control string,
|
control string,
|
||||||
rtpmapPart1 string) (*TrackPCMA, error,
|
rtpmapPart1 string) (*TrackPCMA, error,
|
||||||
|
@@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackPCMANew(t *testing.T) {
|
func TestTrackPCMANew(t *testing.T) {
|
||||||
track := NewTrackPCMA()
|
track := &TrackPCMA{}
|
||||||
require.Equal(t, "", track.GetControl())
|
require.Equal(t, "", track.GetControl())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackPCMAClone(t *testing.T) {
|
func TestTrackPCMAClone(t *testing.T) {
|
||||||
track := NewTrackPCMA()
|
track := &TrackPCMA{}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -21,7 +21,7 @@ func TestTrackPCMAClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackPCMAMediaDescription(t *testing.T) {
|
func TestTrackPCMAMediaDescription(t *testing.T) {
|
||||||
track := NewTrackPCMA()
|
track := &TrackPCMA{}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -12,11 +12,6 @@ type TrackPCMU struct {
|
|||||||
trackBase
|
trackBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTrackPCMU allocates a TrackPCMU.
|
|
||||||
func NewTrackPCMU() *TrackPCMU {
|
|
||||||
return &TrackPCMU{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTrackPCMUFromMediaDescription(
|
func newTrackPCMUFromMediaDescription(
|
||||||
control string,
|
control string,
|
||||||
rtpmapPart1 string) (*TrackPCMU, error,
|
rtpmapPart1 string) (*TrackPCMU, error,
|
||||||
|
@@ -8,12 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTrackPCMUNew(t *testing.T) {
|
func TestTrackPCMUNew(t *testing.T) {
|
||||||
track := NewTrackPCMU()
|
track := &TrackPCMU{}
|
||||||
require.Equal(t, "", track.GetControl())
|
require.Equal(t, "", track.GetControl())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackPCMUClone(t *testing.T) {
|
func TestTrackPCMUClone(t *testing.T) {
|
||||||
track := NewTrackPCMU()
|
track := &TrackPCMU{}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -21,7 +21,7 @@ func TestTrackPCMUClone(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackPCMUMediaDescription(t *testing.T) {
|
func TestTrackPCMUMediaDescription(t *testing.T) {
|
||||||
track := NewTrackPCMU()
|
track := &TrackPCMU{}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
130
track_test.go
130
track_test.go
@@ -72,15 +72,14 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackAAC{
|
&TrackAAC{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
typ: 2,
|
Type: 2,
|
||||||
sampleRate: 48000,
|
SampleRate: 48000,
|
||||||
channelCount: 2,
|
ChannelCount: 2,
|
||||||
aotSpecificConfig: []byte{0x01, 0x02},
|
AOTSpecificConfig: []byte{0x01, 0x02},
|
||||||
mpegConf: []byte{0x11, 0x90, 0x08, 0x10},
|
SizeLength: 13,
|
||||||
sizeLength: 13,
|
IndexLength: 3,
|
||||||
indexLength: 3,
|
IndexDeltaLength: 3,
|
||||||
indexDeltaLength: 3,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -103,14 +102,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackAAC{
|
&TrackAAC{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
typ: 2,
|
Type: 2,
|
||||||
sampleRate: 48000,
|
SampleRate: 48000,
|
||||||
channelCount: 2,
|
ChannelCount: 2,
|
||||||
mpegConf: []byte{0x11, 0x90},
|
SizeLength: 13,
|
||||||
sizeLength: 13,
|
IndexLength: 3,
|
||||||
indexLength: 3,
|
IndexDeltaLength: 3,
|
||||||
indexDeltaLength: 3,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -133,14 +131,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackAAC{
|
&TrackAAC{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
typ: 2,
|
Type: 2,
|
||||||
sampleRate: 48000,
|
SampleRate: 48000,
|
||||||
channelCount: 2,
|
ChannelCount: 2,
|
||||||
mpegConf: []byte{0x11, 0x90},
|
SizeLength: 13,
|
||||||
sizeLength: 13,
|
IndexLength: 3,
|
||||||
indexLength: 3,
|
IndexDeltaLength: 3,
|
||||||
indexDeltaLength: 3,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -167,14 +164,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackAAC{
|
&TrackAAC{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
typ: 2,
|
Type: 2,
|
||||||
sampleRate: 48000,
|
SampleRate: 48000,
|
||||||
channelCount: 2,
|
ChannelCount: 2,
|
||||||
mpegConf: []byte{0x11, 0x90},
|
SizeLength: 13,
|
||||||
sizeLength: 13,
|
IndexLength: 0,
|
||||||
indexLength: 0,
|
IndexDeltaLength: 0,
|
||||||
indexDeltaLength: 0,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -197,9 +193,9 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackOpus{
|
&TrackOpus{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
sampleRate: 48000,
|
SampleRate: 48000,
|
||||||
channelCount: 2,
|
ChannelCount: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -245,13 +241,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackH264{
|
&TrackH264{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
sps: []byte{
|
SPS: []byte{
|
||||||
0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0,
|
0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0,
|
||||||
0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
|
0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
|
||||||
0x00, 0x03, 0x00, 0x3d, 0x08,
|
0x00, 0x03, 0x00, 0x3d, 0x08,
|
||||||
},
|
},
|
||||||
pps: []byte{
|
PPS: []byte{
|
||||||
0x68, 0xee, 0x3c, 0x80,
|
0x68, 0xee, 0x3c, 0x80,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -272,7 +268,7 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackH264{
|
&TrackH264{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -296,14 +292,14 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackH264{
|
&TrackH264{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
sps: []byte{
|
SPS: []byte{
|
||||||
0x67, 0x64, 0x00, 0x1f, 0xac, 0xd9, 0x40, 0x50,
|
0x67, 0x64, 0x00, 0x1f, 0xac, 0xd9, 0x40, 0x50,
|
||||||
0x05, 0xbb, 0x01, 0x6c, 0x80, 0x00, 0x00, 0x03,
|
0x05, 0xbb, 0x01, 0x6c, 0x80, 0x00, 0x00, 0x03,
|
||||||
0x00, 0x80, 0x00, 0x00, 0x1e, 0x07, 0x8c, 0x18,
|
0x00, 0x80, 0x00, 0x00, 0x1e, 0x07, 0x8c, 0x18,
|
||||||
0xcb,
|
0xcb,
|
||||||
},
|
},
|
||||||
pps: []byte{
|
PPS: []byte{
|
||||||
0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
|
0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -329,17 +325,17 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackH264{
|
&TrackH264{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
sps: []byte{
|
SPS: []byte{
|
||||||
0x67, 0x64, 0x00, 0x29, 0xac, 0x13, 0x31, 0x40,
|
0x67, 0x64, 0x00, 0x29, 0xac, 0x13, 0x31, 0x40,
|
||||||
0x78, 0x04, 0x47, 0xde, 0x03, 0xea, 0x02, 0x02,
|
0x78, 0x04, 0x47, 0xde, 0x03, 0xea, 0x02, 0x02,
|
||||||
0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00,
|
0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00,
|
||||||
0x00, 0x06, 0x52, 0x80,
|
0x00, 0x06, 0x52, 0x80,
|
||||||
},
|
},
|
||||||
pps: []byte{
|
PPS: []byte{
|
||||||
0x68, 0xfa, 0x8f, 0x2c,
|
0x68, 0xfa, 0x8f, 0x2c,
|
||||||
},
|
},
|
||||||
extradata: []byte{
|
Extradata: []byte{
|
||||||
0x68, 0xfa, 0x8f, 0x2c,
|
0x68, 0xfa, 0x8f, 0x2c,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -365,13 +361,13 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackH265{
|
&TrackH265{
|
||||||
payloadType: 96,
|
PayloadType: 96,
|
||||||
vps: []byte{
|
VPS: []byte{
|
||||||
0x40, 0x1, 0xc, 0x1, 0xff, 0xff, 0x1, 0x60,
|
0x40, 0x1, 0xc, 0x1, 0xff, 0xff, 0x1, 0x60,
|
||||||
0x0, 0x0, 0x3, 0x0, 0x90, 0x0, 0x0, 0x3,
|
0x0, 0x0, 0x3, 0x0, 0x90, 0x0, 0x0, 0x3,
|
||||||
0x0, 0x0, 0x3, 0x0, 0x78, 0x99, 0x98, 0x9,
|
0x0, 0x0, 0x3, 0x0, 0x78, 0x99, 0x98, 0x9,
|
||||||
},
|
},
|
||||||
sps: []byte{
|
SPS: []byte{
|
||||||
0x42, 0x1, 0x1, 0x1, 0x60, 0x0, 0x0, 0x3,
|
0x42, 0x1, 0x1, 0x1, 0x60, 0x0, 0x0, 0x3,
|
||||||
0x0, 0x90, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3,
|
0x0, 0x90, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3,
|
||||||
0x0, 0x78, 0xa0, 0x3, 0xc0, 0x80, 0x10, 0xe5,
|
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,
|
0x0, 0x3, 0x0, 0x10, 0x0, 0x0, 0x3, 0x1,
|
||||||
0xe0, 0x80,
|
0xe0, 0x80,
|
||||||
},
|
},
|
||||||
pps: []byte{
|
PPS: []byte{
|
||||||
0x44, 0x1, 0xc1, 0x72, 0xb4, 0x62, 0x40,
|
0x44, 0x1, 0xc1, 0x72, 0xb4, 0x62, 0x40,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -397,10 +393,26 @@ func TestTrackNewFromMediaDescription(t *testing.T) {
|
|||||||
Key: "rtpmap",
|
Key: "rtpmap",
|
||||||
Value: "96 VP9/90000",
|
Value: "96 VP9/90000",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Key: "fmtp",
|
||||||
|
Value: "96 max-fr=123;max-fs=456;profile-id=789",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&TrackVP9{
|
&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{
|
&TrackGeneric{
|
||||||
clockRate: 90000,
|
Media: "video",
|
||||||
media: "video",
|
Formats: []string{"98", "96"},
|
||||||
formats: []string{"98", "96"},
|
RTPMap: "98 H265/90000",
|
||||||
rtpmap: "98 H265/90000",
|
FMTP: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " +
|
||||||
fmtp: "98 profile-id=1; sprop-vps=QAEMAf//AWAAAAMAAAMAAAMAAAMAlqwJ; " +
|
|
||||||
"sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=",
|
"sprop-sps=QgEBAWAAAAMAAAMAAAMAAAMAlqADwIAQ5Za5JMmuWcBSSgAAB9AAAHUwgkA=; sprop-pps=RAHgdrAwxmQ=",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -834,8 +845,7 @@ func TestTrackURL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTrackURLError(t *testing.T) {
|
func TestTrackURLError(t *testing.T) {
|
||||||
track, err := NewTrackH264(96, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x05, 0x06, 0x07, 0x08}, nil)
|
track := &TrackH264{}
|
||||||
require.NoError(t, err)
|
_, err := track.url(nil)
|
||||||
_, err = track.url(nil)
|
|
||||||
require.EqualError(t, err, "Content-Base header not provided")
|
require.EqualError(t, err, "Content-Base header not provided")
|
||||||
}
|
}
|
||||||
|
63
track_vp9.go
63
track_vp9.go
@@ -11,20 +11,10 @@ import (
|
|||||||
// TrackVP9 is a VP9 track.
|
// TrackVP9 is a VP9 track.
|
||||||
type TrackVP9 struct {
|
type TrackVP9 struct {
|
||||||
trackBase
|
trackBase
|
||||||
payloadType uint8
|
PayloadType uint8
|
||||||
maxFR *int
|
MaxFR *int
|
||||||
maxFS *int
|
MaxFS *int
|
||||||
profileID *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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTrackVP9FromMediaDescription(
|
func newTrackVP9FromMediaDescription(
|
||||||
@@ -33,10 +23,10 @@ func newTrackVP9FromMediaDescription(
|
|||||||
md *psdp.MediaDescription,
|
md *psdp.MediaDescription,
|
||||||
) (*TrackVP9, error) {
|
) (*TrackVP9, error) {
|
||||||
t := &TrackVP9{
|
t := &TrackVP9{
|
||||||
|
PayloadType: payloadType,
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: control,
|
control: control,
|
||||||
},
|
},
|
||||||
payloadType: payloadType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.fillParamsFromMediaDescription(md)
|
t.fillParamsFromMediaDescription(md)
|
||||||
@@ -74,7 +64,7 @@ func (t *TrackVP9) fillParamsFromMediaDescription(md *psdp.MediaDescription) err
|
|||||||
return fmt.Errorf("invalid max-fr (%v)", tmp[1])
|
return fmt.Errorf("invalid max-fr (%v)", tmp[1])
|
||||||
}
|
}
|
||||||
v2 := int(val)
|
v2 := int(val)
|
||||||
t.maxFR = &v2
|
t.MaxFR = &v2
|
||||||
|
|
||||||
case "max-fs":
|
case "max-fs":
|
||||||
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
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])
|
return fmt.Errorf("invalid max-fs (%v)", tmp[1])
|
||||||
}
|
}
|
||||||
v2 := int(val)
|
v2 := int(val)
|
||||||
t.maxFS = &v2
|
t.MaxFS = &v2
|
||||||
|
|
||||||
case "profile-id":
|
case "profile-id":
|
||||||
val, err := strconv.ParseUint(tmp[1], 10, 64)
|
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])
|
return fmt.Errorf("invalid profile-id (%v)", tmp[1])
|
||||||
}
|
}
|
||||||
v2 := int(val)
|
v2 := int(val)
|
||||||
t.profileID = &v2
|
t.ProfileID = &v2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,43 +95,28 @@ func (t *TrackVP9) ClockRate() int {
|
|||||||
func (t *TrackVP9) clone() Track {
|
func (t *TrackVP9) clone() Track {
|
||||||
return &TrackVP9{
|
return &TrackVP9{
|
||||||
trackBase: t.trackBase,
|
trackBase: t.trackBase,
|
||||||
payloadType: t.payloadType,
|
PayloadType: t.PayloadType,
|
||||||
maxFR: t.maxFR,
|
MaxFR: t.MaxFR,
|
||||||
maxFS: t.maxFS,
|
MaxFS: t.MaxFS,
|
||||||
profileID: t.profileID,
|
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.
|
// MediaDescription returns the track media description in SDP format.
|
||||||
func (t *TrackVP9) MediaDescription() *psdp.MediaDescription {
|
func (t *TrackVP9) MediaDescription() *psdp.MediaDescription {
|
||||||
typ := strconv.FormatInt(int64(t.payloadType), 10)
|
typ := strconv.FormatInt(int64(t.PayloadType), 10)
|
||||||
|
|
||||||
fmtp := typ
|
fmtp := typ
|
||||||
|
|
||||||
var tmp []string
|
var tmp []string
|
||||||
if t.maxFR != nil {
|
if t.MaxFR != nil {
|
||||||
tmp = append(tmp, "max-fr="+strconv.FormatInt(int64(*t.maxFR), 10))
|
tmp = append(tmp, "max-fr="+strconv.FormatInt(int64(*t.MaxFR), 10))
|
||||||
}
|
}
|
||||||
if t.maxFS != nil {
|
if t.MaxFS != nil {
|
||||||
tmp = append(tmp, "max-fs="+strconv.FormatInt(int64(*t.maxFS), 10))
|
tmp = append(tmp, "max-fs="+strconv.FormatInt(int64(*t.MaxFS), 10))
|
||||||
}
|
}
|
||||||
if t.profileID != nil {
|
if t.ProfileID != nil {
|
||||||
tmp = append(tmp, "profile-id="+strconv.FormatInt(int64(*t.profileID), 10))
|
tmp = append(tmp, "profile-id="+strconv.FormatInt(int64(*t.ProfileID), 10))
|
||||||
}
|
}
|
||||||
if tmp != nil {
|
if tmp != nil {
|
||||||
fmtp += " " + strings.Join(tmp, ";")
|
fmtp += " " + strings.Join(tmp, ";")
|
||||||
|
@@ -7,22 +7,16 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"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) {
|
func TestTracVP9Clone(t *testing.T) {
|
||||||
maxFR := 123
|
maxFR := 123
|
||||||
maxFS := 456
|
maxFS := 456
|
||||||
profileID := 789
|
profileID := 789
|
||||||
track := NewTrackVP9(96, &maxFR, &maxFS, &profileID)
|
track := &TrackVP9{
|
||||||
|
PayloadType: 96,
|
||||||
|
MaxFR: &maxFR,
|
||||||
|
MaxFS: &maxFS,
|
||||||
|
ProfileID: &profileID,
|
||||||
|
}
|
||||||
|
|
||||||
clone := track.clone()
|
clone := track.clone()
|
||||||
require.NotSame(t, track, clone)
|
require.NotSame(t, track, clone)
|
||||||
@@ -33,7 +27,12 @@ func TestTrackVP9MediaDescription(t *testing.T) {
|
|||||||
maxFR := 123
|
maxFR := 123
|
||||||
maxFS := 456
|
maxFS := 456
|
||||||
profileID := 789
|
profileID := 789
|
||||||
track := NewTrackVP9(96, &maxFR, &maxFS, &profileID)
|
track := &TrackVP9{
|
||||||
|
PayloadType: 96,
|
||||||
|
MaxFR: &maxFR,
|
||||||
|
MaxFS: &maxFS,
|
||||||
|
ProfileID: &profileID,
|
||||||
|
}
|
||||||
|
|
||||||
require.Equal(t, &psdp.MediaDescription{
|
require.Equal(t, &psdp.MediaDescription{
|
||||||
MediaName: psdp.MediaName{
|
MediaName: psdp.MediaName{
|
||||||
|
@@ -74,9 +74,9 @@ func TestTracksReadSkipGenericTracksWithoutClockRate(t *testing.T) {
|
|||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
control: "rtsp://10.0.100.50/profile5/media.smp/trackID=v",
|
control: "rtsp://10.0.100.50/profile5/media.smp/trackID=v",
|
||||||
},
|
},
|
||||||
payloadType: 97,
|
PayloadType: 97,
|
||||||
sps: []byte{0x67, 0x64, 0x00, 0x28, 0xac, 0xb4, 0x03, 0xc0, 0x11, 0x3f, 0x2a},
|
SPS: []byte{0x67, 0x64, 0x00, 0x28, 0xac, 0xb4, 0x03, 0xc0, 0x11, 0x3f, 0x2a},
|
||||||
pps: []byte{0x68, 0xee, 0x01, 0x9e, 0x2c},
|
PPS: []byte{0x68, 0xee, 0x01, 0x9e, 0x2c},
|
||||||
},
|
},
|
||||||
&TrackPCMU{
|
&TrackPCMU{
|
||||||
trackBase: trackBase{
|
trackBase: trackBase{
|
||||||
|
Reference in New Issue
Block a user