From 6750a1eb8aa4c0ede055af672828baf7a88610bf Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Sun, 21 Sep 2025 18:08:27 +0200 Subject: [PATCH] sdp: fix compatibility with a Uniview camera (bluenviron/mediamtx#5008) (#903) --- pkg/sdp/sdp.go | 2 + pkg/sdp/sdp_test.go | 99 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/pkg/sdp/sdp.go b/pkg/sdp/sdp.go index 10fb770a..c41226ed 100644 --- a/pkg/sdp/sdp.go +++ b/pkg/sdp/sdp.go @@ -91,6 +91,8 @@ func (s *SessionDescription) unmarshalOrigin(value string) error { if strings.HasSuffix(value, " IN") { value += " IP4" + } else if strings.HasSuffix(value, " IN ") { + value += "IP4" } if strings.HasSuffix(value, "IN IP4") { diff --git a/pkg/sdp/sdp_test.go b/pkg/sdp/sdp_test.go index 8bef313a..6869932b 100644 --- a/pkg/sdp/sdp_test.go +++ b/pkg/sdp/sdp_test.go @@ -3093,8 +3093,7 @@ var cases = []struct { }, }, }, - - { + { //nolint:dupl "issue gortsplib/618 (Uniview IPC2125LE-ADF28KM-H)", []byte("v=0\r\n" + "o=- 1001 1 IN\r\n" + @@ -3241,6 +3240,102 @@ var cases = []struct { }, }, }, + { //nolint:dupl + "issue mediamtx/5008 (Uniview IPC2122LB-SF28K-A)", + []byte("v=0\r\n" + + "o=- 1001 1 IN \r\n" + + "s=VCP IPC Realtime stream\r\n" + + "m=video 0 RTP/AVP 105\r\n" + + "c=IN\r\n" + + "a=control:rtsp://10.0.0.1/media/video1/video\r\n" + + "a=rtpmap:105 H264/90000\r\n" + + "a=fmtp:105 profile-level-id=640028; packetization-mode=1; " + + "sprop-parameter-sets=Z2QAKKw7UDwBE/LCAAAH0AAA6mEI,aOqPLA==\r\n" + + "a=recvonly\r\n" + + "m=application 0 RTP/AVP 107\r\n" + + "c=IN\r\n" + + "a=control:rtsp://10.0.0.1/media/video1/metadata\r\n" + + "a=rtpmap:107 vnd.onvif.metadata/90000\r\n" + + "a=fmtp:107 DecoderTag=h3c-v3 RTCP=0\r\n" + + "a=recvonly\r\n"), + []byte("v=0\r\n" + + "o=- 1001 1 IN IP4 \r\n" + + "s=VCP IPC Realtime stream\r\n" + + "m=video 0 RTP/AVP 105\r\n" + + "a=control:rtsp://10.0.0.1/media/video1/video\r\n" + + "a=rtpmap:105 H264/90000\r\n" + + "a=fmtp:105 profile-level-id=640028; packetization-mode=1; " + + "sprop-parameter-sets=Z2QAKKw7UDwBE/LCAAAH0AAA6mEI,aOqPLA==\r\n" + + "a=recvonly\r\n" + + "m=application 0 RTP/AVP 107\r\n" + + "a=control:rtsp://10.0.0.1/media/video1/metadata\r\n" + + "a=rtpmap:107 vnd.onvif.metadata/90000\r\n" + + "a=fmtp:107 DecoderTag=h3c-v3 RTCP=0\r\n" + + "a=recvonly\r\n"), + SessionDescription{ + Origin: psdp.Origin{ + Username: "-", + SessionID: 1001, + SessionVersion: 1, + NetworkType: "IN", + AddressType: "IP4", + }, + SessionName: "VCP IPC Realtime stream", + MediaDescriptions: []*psdp.MediaDescription{ + { + MediaName: psdp.MediaName{ + Media: "video", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"105"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "control", + Value: "rtsp://10.0.0.1/media/video1/video", + }, + { + Key: "rtpmap", + Value: "105 H264/90000", + }, + { + Key: "fmtp", + Value: "105 profile-level-id=640028; packetization-mode=1; " + + "sprop-parameter-sets=Z2QAKKw7UDwBE/LCAAAH0AAA6mEI,aOqPLA==", + }, + { + Key: "recvonly", + Value: "", + }, + }, + }, + { + MediaName: psdp.MediaName{ + Media: "application", + Protos: []string{"RTP", "AVP"}, + Formats: []string{"107"}, + }, + Attributes: []psdp.Attribute{ + { + Key: "control", + Value: "rtsp://10.0.0.1/media/video1/metadata", + }, + { + Key: "rtpmap", + Value: "107 vnd.onvif.metadata/90000", + }, + { + Key: "fmtp", + Value: "107 DecoderTag=h3c-v3 RTCP=0", + }, + { + Key: "recvonly", + Value: "", + }, + }, + }, + }, + }, + }, } func TestUnmarshal(t *testing.T) {