From 8aa3ff425be5d58d5a1939ac09f4ceb94c5acf07 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 27 Mar 2021 22:23:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84sdp=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Extension/Frame.h | 3 +- webrtc/Sdp.h | 284 ++++++++++++++++++++++++++++++--------- webrtc/WebRtcTransport.h | 2 +- 3 files changed, 223 insertions(+), 66 deletions(-) diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index 4988ac06..5f60a68d 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -38,7 +38,8 @@ typedef enum { TrackVideo = 0, TrackAudio, TrackTitle, - TrackMax = 3 + TrackData, + TrackMax = 4 } TrackType; /** diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 6756b11c..dfe47c54 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -5,58 +5,112 @@ #ifndef ZLMEDIAKIT_SDP_H #define ZLMEDIAKIT_SDP_H -#include #include +#include +#include "Extension/Frame.h" using namespace std; +using namespace mediakit; -enum class RtpDirection { - invalid = -1, - //只发送 - sendonly, - //只接收 - revonly, - //同时发送接收 - sendrecv, - //禁止发送数据 - inactive -}; +//https://datatracker.ietf.org/doc/rfc4566/?include_text=1 -enum class DtlsRole { - invalid = -1, - //客户端 - active, - //服务端 - passive, - //既可作做客户端也可以做服务端 - actpass, -}; - -enum class SdpType { - invalid = -1, - offer, - answer -}; - -// //v=0 -//o=- 7268199939077294076 2 IN IP4 127.0.0.1 +//o=- 2584450093346841581 2 IN IP4 127.0.0.1 //s=- //t=0 0 -//a=group:BUNDLE video -//a=msid-semantic: WMS -//m=video 9 RTP/SAVPF 96 +//a=group:BUNDLE audio video data +//a=msid-semantic: WMS 616cfbb1-33a3-4d8c-8275-a199d6005549 +//m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126 //c=IN IP4 0.0.0.0 //a=rtcp:9 IN IP4 0.0.0.0 -//a=ice-ufrag:y94W -//a=ice-pwd:fuz1hZCAarezk35fruVGfdyP -//a=ice-options:trickle -//a=fingerprint:sha-256 FF:8C:29:B8:B3:2B:45:F5:21:D2:47:D5:EE:B7:F8:BB:F1:DC:95:47:7B:20:B4:59:75:0F:16:93:D0:AC:D2:73 -//a=setup:active -//a=mid:video -//a=recvonly +//a=ice-ufrag:sXJ3 +//a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV +//a=fingerprint:sha-256 22:14:B5:AF:66:12:C7:C7:8D:EF:4B:DE:40:25:ED:5D:8F:17:54:DD:88:33:C0:13:2E:FD:1A:FA:7E:7A:1B:79 +//a=setup:actpass +//a=mid:audio +//a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level +//a=sendrecv //a=rtcp-mux -//a=rtpmap:96 H264/90000 -//a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f +//a=rtpmap:111 opus/48000/2 +//a=rtcp-fb:111 transport-cc +//a=fmtp:111 minptime=10;useinbandfec=1 +//a=rtpmap:103 ISAC/16000 +//a=rtpmap:104 ISAC/32000 +//a=rtpmap:9 G722/8000 +//a=rtpmap:0 PCMU/8000 +//a=rtpmap:8 PCMA/8000 +//a=rtpmap:106 CN/32000 +//a=rtpmap:105 CN/16000 +//a=rtpmap:13 CN/8000 +//a=rtpmap:110 telephone-event/48000 +//a=rtpmap:112 telephone-event/32000 +//a=rtpmap:113 telephone-event/16000 +//a=rtpmap:126 telephone-event/8000 +//a=ssrc:120276603 cname:iSkJ2vn5cYYubTve +//a=ssrc:120276603 msid:616cfbb1-33a3-4d8c-8275-a199d6005549 1da3d329-7399-4fe9-b20f-69606bebd363 +//a=ssrc:120276603 mslabel:616cfbb1-33a3-4d8c-8275-a199d6005549 +//a=ssrc:120276603 label:1da3d329-7399-4fe9-b20f-69606bebd363 +//m=video 9 UDP/TLS/RTP/SAVPF 96 98 100 102 127 97 99 101 125 +//c=IN IP4 0.0.0.0 +//a=rtcp:9 IN IP4 0.0.0.0 +//a=ice-ufrag:sXJ3 +//a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV +//a=fingerprint:sha-256 22:14:B5:AF:66:12:C7:C7:8D:EF:4B:DE:40:25:ED:5D:8F:17:54:DD:88:33:C0:13:2E:FD:1A:FA:7E:7A:1B:79 +//a=setup:actpass +//a=mid:video +//a=extmap:2 urn:ietf:params:rtp-hdrext:toffset +//a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time +//a=extmap:4 urn:3gpp:video-orientation +//a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 +//a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay +//a=sendrecv +//a=rtcp-mux +//a=rtcp-rsize +//a=rtpmap:96 VP8/90000 +//a=rtcp-fb:96 ccm fir +//a=rtcp-fb:96 nack +//a=rtcp-fb:96 nack pli +//a=rtcp-fb:96 goog-remb +//a=rtcp-fb:96 transport-cc +//a=rtpmap:98 VP9/90000 +//a=rtcp-fb:98 ccm fir +//a=rtcp-fb:98 nack +//a=rtcp-fb:98 nack pli +//a=rtcp-fb:98 goog-remb +//a=rtcp-fb:98 transport-cc +//a=rtpmap:100 H264/90000 +//a=rtcp-fb:100 ccm fir +//a=rtcp-fb:100 nack +//a=rtcp-fb:100 nack pli +//a=rtcp-fb:100 goog-remb +//a=rtcp-fb:100 transport-cc +//a=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f +//a=rtpmap:102 red/90000 +//a=rtpmap:127 ulpfec/90000 +//a=rtpmap:97 rtx/90000 +//a=fmtp:97 apt=96 +//a=rtpmap:99 rtx/90000 +//a=fmtp:99 apt=98 +//a=rtpmap:101 rtx/90000 +//a=fmtp:101 apt=100 +//a=rtpmap:125 rtx/90000 +//a=fmtp:125 apt=102 +//a=ssrc-group:FID 2580761338 611523443 +//a=ssrc:2580761338 cname:iSkJ2vn5cYYubTve +//a=ssrc:2580761338 msid:616cfbb1-33a3-4d8c-8275-a199d6005549 bf270496-a23e-47b5-b901-ef23096cd961 +//a=ssrc:2580761338 mslabel:616cfbb1-33a3-4d8c-8275-a199d6005549 +//a=ssrc:2580761338 label:bf270496-a23e-47b5-b901-ef23096cd961 +//a=ssrc:611523443 cname:iSkJ2vn5cYYubTve +//a=ssrc:611523443 msid:616cfbb1-33a3-4d8c-8275-a199d6005549 bf270496-a23e-47b5-b901-ef23096cd961 +//a=ssrc:611523443 mslabel:616cfbb1-33a3-4d8c-8275-a199d6005549 +//a=ssrc:611523443 label:bf270496-a23e-47b5-b901-ef23096cd961 +//m=application 9 DTLS/SCTP 5000 +//c=IN IP4 0.0.0.0 +//a=ice-ufrag:sXJ3 +//a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV +//a=fingerprint:sha-256 22:14:B5:AF:66:12:C7:C7:8D:EF:4B:DE:40:25:ED:5D:8F:17:54:DD:88:33:C0:13:2E:FD:1A:FA:7E:7A:1B:79 +//a=setup:actpass +//a=mid:data +//a=sctpmap:5000 webrtc-datachannel 1024 //Session description // v= (protocol version) @@ -88,33 +142,57 @@ enum class SdpType { // k=* (encryption key) // a=* (zero or more media attribute lines) +enum class RtpDirection { + invalid = -1, + //只发送 + sendonly, + //只接收 + revonly, + //同时发送接收 + sendrecv, + //禁止发送数据 + inactive +}; + +enum class DtlsRole { + invalid = -1, + //客户端 + active, + //服务端 + passive, + //既可作做客户端也可以做服务端 + actpass, +}; + +enum class SdpType { + invalid = -1, + offer, + answer +}; + class SdpItem { public: SdpItem() = default; virtual ~SdpItem() = default; virtual void parse(const string &str) = 0; virtual string toString() const = 0; + virtual const char* getKey() = 0; }; class SdpTime : public SdpItem{ public: - float start; - float end; - void parse(const string &str) override; - string toString() const override; -}; - -class SdpAttr : public SdpItem{ -public: - string name; - string value; + //5.9. Timing ("t=") + // t= + uint64_t start; + uint64_t stop; void parse(const string &str) override; string toString() const override; + const char* getKey() override { return "t";} }; class SdpOrigin : public SdpItem{ public: - // https://datatracker.ietf.org/doc/rfc4566/?include_text=1 5.2. Origin ("o=") + // 5.2. Origin ("o=") // o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5 // o= string username; @@ -125,11 +203,12 @@ public: string address; void parse(const string &str) override; string toString() const override; + const char* getKey() override { return "o";} }; class SdpConnection : public SdpItem { public: - // https://datatracker.ietf.org/doc/rfc4566/?include_text=1 5.7. Connection Data ("c=") + // 5.7. Connection Data ("c=") // c=IN IP4 224.2.17.12/127 // c= string nettype; @@ -137,12 +216,75 @@ public: string address; void parse(const string &str) override; string toString() const override; + const char* getKey() override { return "c";} +}; + +class SdpBandwidth : public SdpItem { +public: + //5.8. Bandwidth ("b=") + //b=: + + //AS、CT + string bwtype; + int bandwidth; + + void parse(const string &str) override; + string toString() const override; + const char* getKey() override { return "b";} +}; + +class SdpMedia : public SdpItem { +public: + // 5.14. Media Descriptions ("m=") + // m= ... + TrackType type; + uint16_t port; + vector proto; + vector fmt; + + void parse(const string &str) override; + string toString() const override; + const char* getKey() override { return "m";} +}; + +class SdpAttr : public SdpItem{ +public: + //5.13. Attributes ("a=") + //a= + //a=: + string name; + string value; + void parse(const string &str) override; + string toString() const override; + const char* getKey() override { return "a";} +}; + +class SdpAttrGroup : public SdpItem{ +public: + //a=group:BUNDLE line with all the 'mid' identifiers part of the + // BUNDLE group is included at the session-level. + //a=group:LS session level attribute MUST be included wth the 'mid' + // identifiers that are part of the same lip sync group. + string type; + vector mid; + void parse(const string &str) override; + string toString() const override; + const char* getKey() override { return "group";} }; class RtcMedia { public: + //m= ... + SdpMedia media; + //c= + SdpConnection connection; + //a=: + vector attributes; + bool haveAttr(const char *attr) const; + string getAttrValue(const char *attr) const; }; + class RtcSdp { public: /////Session description(会话级别描述)//// @@ -152,19 +294,33 @@ public: SdpOrigin origin; //s= (session name) string session_name; - //i=* (session information) - string session_information; - //c=* (connection information -- not required if included in all media) - SdpConnection connection; - - //// Time description //// //t= (time the session is active) SdpTime time; - //r=* (zero or more repeat times) - int repeat; - //a=* (zero or more media attribute lines) - list attributes; + //// 非必须 //// + //i=* (session information) + string information; + //u=* (URI of description) + string url; + //e=* (email address) + string email; + //p=* (phone number) + string phone; + //c=* (connection information -- not required if included in all media) + SdpConnection connection; + //b=* (zero or more bandwidth information lines) + SdpBandwidth bandwidth; + //z=* (time zone adjustments) + //z= .... + string time_zone; + //k=* (encryption key) + //k=, k=: + string crypt_key; + //r=* (zero or more repeat times) + //r= + string repeat; + //a=* (zero or more media attribute lines) + vector attributes; }; diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 7f32612a..2842bee8 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -95,7 +95,7 @@ public: protected: void onWrite(const char *buf, size_t len, struct sockaddr_in *dst) override; - int getPayloadType() const ; + int getPayloadType() const override; uint32_t getSSRC() const override; uint16_t getPort() const override; std::string getIP() const override;