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