ZLMediaKit/webrtc/Sdp.h

491 lines
15 KiB
C++
Raw Normal View History

2021-03-27 18:33:20 +08:00
//
// Created by xzl on 2021/3/27.
//
#ifndef ZLMEDIAKIT_SDP_H
#define ZLMEDIAKIT_SDP_H
#include <string>
2021-03-27 22:23:38 +08:00
#include <vector>
#include "Extension/Frame.h"
2021-03-27 18:33:20 +08:00
using namespace std;
2021-03-27 22:23:38 +08:00
using namespace mediakit;
2021-03-27 18:33:20 +08:00
2021-03-27 22:23:38 +08:00
//https://datatracker.ietf.org/doc/rfc4566/?include_text=1
2021-03-27 18:33:20 +08:00
//v=0
2021-03-27 22:23:38 +08:00
//o=- 2584450093346841581 2 IN IP4 127.0.0.1
2021-03-27 18:33:20 +08:00
//s=-
//t=0 0
2021-03-27 22:23:38 +08:00
//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
2021-03-27 18:33:20 +08:00
//c=IN IP4 0.0.0.0
//a=rtcp:9 IN IP4 0.0.0.0
2021-03-27 22:23:38 +08:00
//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: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
2021-03-27 18:33:20 +08:00
//a=mid:video
2021-03-27 22:23:38 +08:00
//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
2021-03-27 18:33:20 +08:00
//a=rtcp-mux
2021-03-27 22:23:38 +08:00
//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
2021-03-28 09:49:34 +08:00
//a=candidate:1 1 udp %u %s %u typ host
2021-03-27 22:23:38 +08:00
//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
2021-03-27 18:33:20 +08:00
//Session description
// v= (protocol version)
// o= (originator and session identifier)
// s= (session name)
// i=* (session information)
// u=* (URI of description)
// e=* (email address)
// p=* (phone number)
// c=* (connection information -- not required if included in
// all media)
// b=* (zero or more bandwidth information lines)
// One or more time descriptions ("t=" and "r=" lines; see below)
// z=* (time zone adjustments)
// k=* (encryption key)
// a=* (zero or more session attribute lines)
// Zero or more media descriptions
//
// Time description
// t= (time the session is active)
// r=* (zero or more repeat times)
//
// Media description, if present
// m= (media name and transport address)
// i=* (media title)
// c=* (connection information -- optional if included at
// session level)
// b=* (zero or more bandwidth information lines)
// k=* (encryption key)
// a=* (zero or more media attribute lines)
2021-03-27 22:23:38 +08:00
enum class RtpDirection {
invalid = -1,
//只发送
sendonly,
//只接收
revonly,
//同时发送接收
sendrecv,
//禁止发送数据
inactive
};
enum class DtlsRole {
invalid = -1,
//客户端
active,
//服务端
passive,
//既可作做客户端也可以做服务端
actpass,
};
enum class SdpType {
invalid = -1,
offer,
answer
};
2021-03-27 18:33:20 +08:00
class SdpItem {
public:
2021-03-28 09:49:34 +08:00
using Ptr = std::shared_ptr<SdpItem>;
string value;
2021-03-27 18:33:20 +08:00
virtual ~SdpItem() = default;
2021-03-28 09:49:34 +08:00
virtual void parse(const string &str) {
value = str;
}
virtual string toString() const {
return value;
}
2021-03-27 22:23:38 +08:00
virtual const char* getKey() = 0;
2021-03-27 18:33:20 +08:00
};
2021-03-28 09:49:34 +08:00
template <char KEY>
class SdpString : public SdpItem{
public:
// *=*
const char* getKey() override { static string key(1, KEY); return key.data();}
};
class SdpCommon : public SdpItem {
public:
string key;
SdpCommon(string key) { this->key = std::move(key); }
const char* getKey() override { return key.data();}
};
2021-03-27 18:33:20 +08:00
class SdpTime : public SdpItem{
public:
2021-03-27 22:23:38 +08:00
//5.9. Timing ("t=")
// t=<start-time> <stop-time>
uint64_t start;
uint64_t stop;
2021-03-28 09:49:34 +08:00
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
const char* getKey() override { return "t";}
2021-03-27 18:33:20 +08:00
};
class SdpOrigin : public SdpItem{
public:
2021-03-27 22:23:38 +08:00
// 5.2. Origin ("o=")
2021-03-27 18:33:20 +08:00
// o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
// o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
string username;
string session_id;
string session_version;
string nettype;
string addrtype;
string address;
2021-03-28 09:49:34 +08:00
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
const char* getKey() override { return "o";}
2021-03-27 18:33:20 +08:00
};
class SdpConnection : public SdpItem {
public:
2021-03-27 22:23:38 +08:00
// 5.7. Connection Data ("c=")
2021-03-27 18:33:20 +08:00
// c=IN IP4 224.2.17.12/127
// c=<nettype> <addrtype> <connection-address>
string nettype;
string addrtype;
string address;
2021-03-28 09:49:34 +08:00
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
const char* getKey() override { return "c";}
};
class SdpBandwidth : public SdpItem {
public:
//5.8. Bandwidth ("b=")
//b=<bwtype>:<bandwidth>
//AS、CT
string bwtype;
int bandwidth;
2021-03-28 09:49:34 +08:00
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
const char* getKey() override { return "b";}
};
class SdpMedia : public SdpItem {
public:
// 5.14. Media Descriptions ("m=")
// m=<media> <port> <proto> <fmt> ...
TrackType type;
uint16_t port;
vector<string> proto;
vector<uint8_t> fmt;
2021-03-28 09:49:34 +08:00
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
const char* getKey() override { return "m";}
};
class SdpAttr : public SdpItem{
public:
2021-03-28 09:49:34 +08:00
using Ptr = std::shared_ptr<SdpAttr>;
2021-03-27 22:23:38 +08:00
//5.13. Attributes ("a=")
//a=<attribute>
//a=<attribute>:<value>
2021-03-28 09:49:34 +08:00
SdpItem::Ptr detail;
2021-03-27 22:23:38 +08:00
void parse(const string &str) override;
2021-03-28 09:49:34 +08:00
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
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<string> mid;
2021-03-28 09:49:34 +08:00
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
2021-03-27 22:23:38 +08:00
const char* getKey() override { return "group";}
2021-03-27 18:33:20 +08:00
};
2021-03-28 09:49:34 +08:00
class SdpAttrMsidSemantic : public SdpItem {
2021-03-27 18:33:20 +08:00
public:
2021-03-28 09:49:34 +08:00
string name{"WMS"};
string mid;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "msid-semantic";}
};
2021-03-27 18:33:20 +08:00
2021-03-28 09:49:34 +08:00
class SdpAttrRtcp : public SdpItem {
public:
// c=IN IP4 224.2.17.12/127
// c=<nettype> <addrtype> <connection-address>
uint16_t port;
string nettype;
string addrtype;
string address;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "rtcp";}
};
class SdpAttrIceUfrag : public SdpItem {
public:
//a=ice-ufrag:sXJ3
string value;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "ice-ufrag";}
};
class SdpAttrIcePwd : public SdpItem {
public:
//a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV
string value;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "ice-pwd";}
};
class SdpAttrFingerprint : public SdpItem {
public:
//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
string algorithm;
string value;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "fingerprint";}
};
class SdpAttrSetup : public SdpItem {
public:
//a=setup:actpass
DtlsRole role{DtlsRole::invalid};
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "setup";}
};
class SdpAttrMid : public SdpItem {
public:
//a=mid:audio
string mid;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "mid";}
};
class SdpAttrExtmap : public SdpItem {
public:
//a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
int index;
string value;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "extmap";}
};
class SdpAttrRtpMap : public SdpItem {
public:
//a=rtpmap:111 opus/48000/2
uint8_t pt;
string codec;
int sample_rate;
int channel;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "rtpmap";}
};
class SdpAttrRtcpFb : public SdpItem {
public:
//a=rtcp-fb:111 transport-cc
uint8_t pt;
string value;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "rtcp-fb";}
};
class SdpAttrFmtp : public SdpItem {
public:
//a=rtcp-fb:111 transport-cc
uint8_t pt;
map<string, string> values;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "fmtp";}
};
class SdpAttrSSRC : public SdpItem {
public:
//a=ssrc:120276603 cname:iSkJ2vn5cYYubTve
uint32_t ssrc;
string key;
string value;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "ssrc";}
};
class SdpAttrSctpMap : public SdpItem {
public:
//a=ssrc:120276603 cname:iSkJ2vn5cYYubTve
uint16_t port;
string name;
int mtu;
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "sctpmap";}
};
class SdpAttrCandidate : public SdpItem {
public:
//a=candidate:%s 1 udp %u %s %u typ %s
void parse(const string &str) override {SdpItem::parse(str); };
string toString() const override { return SdpItem::toString(); };
const char* getKey() override { return "candidate";}
};
class RtcMedia {
public:
vector<SdpItem::Ptr> items;
2021-03-27 22:23:38 +08:00
bool haveAttr(const char *attr) const;
string getAttrValue(const char *attr) const;
2021-03-27 18:33:20 +08:00
};
2021-03-27 22:23:38 +08:00
2021-03-27 18:33:20 +08:00
class RtcSdp {
public:
2021-03-28 09:49:34 +08:00
vector<SdpItem::Ptr> items;
vector<RtcMedia> medias;
void parse(const string &str);
string toString() const;
#if 0
2021-03-27 18:33:20 +08:00
/////Session description会话级别描述////
//v= (protocol version)
int version;
//o= (session origin information )
SdpOrigin origin;
//s= (session name)
string session_name;
2021-03-27 22:23:38 +08:00
//t= (time the session is active)
SdpTime time;
//// 非必须 ////
2021-03-27 18:33:20 +08:00
//i=* (session information)
2021-03-27 22:23:38 +08:00
string information;
//u=* (URI of description)
string url;
//e=* (email address)
string email;
//p=* (phone number)
string phone;
2021-03-27 18:33:20 +08:00
//c=* (connection information -- not required if included in all media)
SdpConnection connection;
2021-03-27 22:23:38 +08:00
//b=* (zero or more bandwidth information lines)
SdpBandwidth bandwidth;
//z=* (time zone adjustments)
//z=<adjustment time> <offset> <adjustment time> <offset> ....
string time_zone;
//k=* (encryption key)
//k=<method>, k=<method>:<encryption key>
string crypt_key;
2021-03-27 18:33:20 +08:00
//r=* (zero or more repeat times)
2021-03-27 22:23:38 +08:00
//r=<repeat interval> <active duration> <offsets from start-time>
string repeat;
2021-03-28 09:49:34 +08:00
#endif
2021-03-27 18:33:20 +08:00
};
#endif //ZLMEDIAKIT_SDP_H