From 4e8fa2e4ab97354ca27178f1d419efad8d234288 Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Sun, 29 Nov 2020 16:10:00 +0100 Subject: [PATCH] fix clock rate computation with standard RTP payload type (https://github.com/aler9/rtsp-simple-server/issues/123) --- track.go | 32 ++++++++++++++++++-- track_test.go | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 track_test.go diff --git a/track.go b/track.go index 9f006e8a..6d8f2dd2 100644 --- a/track.go +++ b/track.go @@ -109,18 +109,44 @@ func NewTrackAAC(id int, config []byte) (*Track, error) { // ClockRate returns the clock rate of the track. func (t *Track) ClockRate() (int, error) { + if len(t.Media.MediaName.Formats) != 1 { + return 0, fmt.Errorf("invalid format (%v)", t.Media.MediaName.Formats) + } + + // get clock rate from payload type + switch t.Media.MediaName.Formats[0] { + case "0", "1", "2", "3", "4", "5", "7", "8", "9", "12", "13", "15", "18": + return 8000, nil + + case "6": + return 16000, nil + + case "10", "11": + return 44100, nil + + case "14", "25", "26", "28", "31", "32", "33", "34": + return 90000, nil + + case "16": + return 11025, nil + + case "17": + return 22050, nil + } + + // get clock rate from rtpmap // https://tools.ietf.org/html/rfc4566 // a=rtpmap: / [/] for _, a := range t.Media.Attributes { if a.Key == "rtpmap" { tmp := strings.Split(a.Value, " ") - if len(tmp) != 2 { - return 0, fmt.Errorf("invalid format (%s)", a.Value) + if len(tmp) < 2 { + return 0, fmt.Errorf("invalid rtpmap (%v)", a.Value) } tmp = strings.Split(tmp[1], "/") if len(tmp) != 2 && len(tmp) != 3 { - return 0, fmt.Errorf("invalid format (%s)", a.Value) + return 0, fmt.Errorf("invalid rtpmap (%v)", a.Value) } v, err := strconv.ParseInt(tmp[1], 10, 64) diff --git a/track_test.go b/track_test.go new file mode 100644 index 00000000..51950f60 --- /dev/null +++ b/track_test.go @@ -0,0 +1,84 @@ +package gortsplib + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTrackClockRate(t *testing.T) { + for _, ca := range []struct { + name string + sdp []byte + clockRate int + }{ + { + "empty encoding parameters", + []byte("v=0\r\n" + + "o=- 38990265062388 38990265062388 IN IP4 192.168.1.142\r\n" + + "s=RTSP Session\r\n" + + "c=IN IP4 192.168.1.142\r\n" + + "t=0 0\r\n" + + "a=control:*\r\n" + + "a=range:npt=0-\r\n" + + "m=video 0 RTP/AVP 96\r\n" + + "a=rtpmap:96 H264/90000 \r\n" + + "a=range:npt=0-\r\n" + + "a=framerate:0S\r\n" + + "a=fmtp:96 profile-level-id=64000c; packetization-mode=1; sprop-parameter-sets=Z2QADKw7ULBLQgAAAwACAAADAD0I,aO48gA==\r\n" + + "a=framerate:25\r\n" + + "a=control:trackID=3\r\n"), + 90000, + }, + { + "static payload type 1", + []byte("v=0\r\n" + + "o=- 38990265062388 38990265062388 IN IP4 192.168.1.142\r\n" + + "s=RTSP Session\r\n" + + "c=IN IP4 192.168.1.142\r\n" + + "t=0 0\r\n" + + "a=control:*\r\n" + + "a=range:npt=0-\r\n" + + "m=audio 0 RTP/AVP 8\r\n" + + "a=control:trackID=4"), + 8000, + }, + { + "static payload type 2", + []byte("v=0\r\n" + + "o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\r\n" + + "s=SDP Seminar\r\n" + + "i=A Seminar on the session description protocol\r\n" + + "u=http://www.example.com/seminars/sdp.pdf\r\n" + + "e=j.doe@example.com (Jane Doe)\r\n" + + "p=+1 617 555-6011\r\n" + + "c=IN IP4 224.2.17.12/127\r\n" + + "b=X-YZ:128\r\n" + + "b=AS:12345\r\n" + + "t=2873397496 2873404696\r\n" + + "t=3034423619 3042462419\r\n" + + "r=604800 3600 0 90000\r\n" + + "z=2882844526 -3600 2898848070 0\r\n" + + "k=prompt\r\n" + + "a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host\r\n" + + "a=recvonly\r\n" + + "m=audio 49170 RTP/AVP 0\r\n" + + "i=Vivamus a posuere nisl\r\n" + + "c=IN IP4 203.0.113.1\r\n" + + "b=X-YZ:128\r\n" + + "k=prompt\r\n" + + "a=sendrecv\r\n"), + 8000, + }, + } { + t.Run(ca.name, func(t *testing.T) { + tracks, err := ReadTracks(ca.sdp) + require.NoError(t, err) + + clockRate, err := tracks[0].ClockRate() + require.NoError(t, err) + + require.Equal(t, clockRate, ca.clockRate) + }) + } +}