| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- /*
- * Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
- *
- * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
- *
- * Use of this source code is governed by MIT-like license that can be found in the
- * LICENSE file in the root of the source tree. All contributing project authors
- * may be found in the AUTHORS file in the root of the source tree.
- */
- #ifndef ZLMEDIAKIT_SDP_H
- #define ZLMEDIAKIT_SDP_H
- #include <set>
- #include <map>
- #include <string>
- #include <vector>
- #include "RtpExt.h"
- #include "assert.h"
- #include "Extension/Frame.h"
- #include "Common/Parser.h"
- namespace mediakit {
- // https://datatracker.ietf.org/doc/rfc4566/?include_text=1
- // https://blog.csdn.net/aggresss/article/details/109850434
- // https://aggresss.blog.csdn.net/article/details/106436703
- // 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)
- enum class RtpDirection {
- invalid = -1,
- // 只发送 [AUTO-TRANSLATED:d7e7fdb7]
- // Send only
- sendonly,
- // 只接收 [AUTO-TRANSLATED:f75ca789]
- // Receive only
- recvonly,
- // 同时发送接收 [AUTO-TRANSLATED:7f900ba1]
- // Send and receive simultaneously
- sendrecv,
- // 禁止发送数据 [AUTO-TRANSLATED:6045b47e]
- // Prohibit sending data
- inactive
- };
- enum class DtlsRole {
- invalid = -1,
- // 客户端 [AUTO-TRANSLATED:915417a2]
- // Client
- active,
- // 服务端 [AUTO-TRANSLATED:03a80b18]
- // Server
- passive,
- // 既可作做客户端也可以做服务端 [AUTO-TRANSLATED:5ab1162e]
- // Can be used as both client and server
- actpass,
- };
- enum class SdpType { invalid = -1, offer, answer };
- DtlsRole getDtlsRole(const std::string &str);
- const char *getDtlsRoleString(DtlsRole role);
- RtpDirection getRtpDirection(const std::string &str);
- const char *getRtpDirectionString(RtpDirection val);
- class SdpItem {
- public:
- using Ptr = std::shared_ptr<SdpItem>;
- virtual ~SdpItem() = default;
- virtual void parse(const std::string &str) { value = str; }
- virtual std::string toString() const { return value; }
- virtual const char *getKey() const = 0;
- void reset() { value.clear(); }
- protected:
- mutable std::string value;
- };
- template <char KEY>
- class SdpString : public SdpItem {
- public:
- SdpString() = default;
- SdpString(std::string val) { value = std::move(val); }
- // *=*
- const char* getKey() const override { static std::string key(1, KEY); return key.data();}
- };
- class SdpCommon : public SdpItem {
- public:
- std::string key;
- SdpCommon(std::string key) { this->key = std::move(key); }
- SdpCommon(std::string key, std::string val) {
- this->key = std::move(key);
- this->value = std::move(val);
- }
- const char *getKey() const override { return key.data(); }
- };
- class SdpTime : public SdpItem {
- public:
- // 5.9. Timing ("t=")
- // t=<start-time> <stop-time>
- uint64_t start { 0 };
- uint64_t stop { 0 };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "t"; }
- };
- class SdpOrigin : public SdpItem {
- public:
- // 5.2. Origin ("o=")
- // o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
- // o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
- std::string username { "-" };
- std::string session_id;
- std::string session_version;
- std::string nettype { "IN" };
- std::string addrtype { "IP4" };
- std::string address { "0.0.0.0" };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "o"; }
- bool empty() const {
- return username.empty() || session_id.empty() || session_version.empty()
- || nettype.empty() || addrtype.empty() || address.empty();
- }
- };
- class SdpConnection : public SdpItem {
- public:
- // 5.7. Connection Data ("c=")
- // c=IN IP4 224.2.17.12/127
- // c=<nettype> <addrtype> <connection-address>
- std::string nettype { "IN" };
- std::string addrtype { "IP4" };
- std::string address { "0.0.0.0" };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "c"; }
- bool empty() const { return address.empty(); }
- };
- class SdpBandwidth : public SdpItem {
- public:
- // 5.8. Bandwidth ("b=")
- // b=<bwtype>:<bandwidth>
- // AS、CT [AUTO-TRANSLATED:65298206]
- // AS, CT
- std::string bwtype { "AS" };
- uint32_t bandwidth { 0 };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "b"; }
- bool empty() const { return bandwidth == 0; }
- };
- class SdpMedia : public SdpItem {
- public:
- // 5.14. Media Descriptions ("m=")
- // m=<media> <port> <proto> <fmt> ...
- TrackType type;
- uint16_t port;
- // RTP/AVP:应用场景为视频/音频的 RTP 协议。参考 RFC 3551 [AUTO-TRANSLATED:7a9d7e86]
- // RTP/AVP: The application scenario is the RTP protocol for video/audio. Refer to RFC 3551
- // RTP/SAVP:应用场景为视频/音频的 SRTP 协议。参考 RFC 3711 [AUTO-TRANSLATED:7989a619]
- // RTP/SAVP: The application scenario is the SRTP protocol for video/audio. Refer to RFC 3711
- // RTP/AVPF: 应用场景为视频/音频的 RTP 协议,支持 RTCP-based Feedback。参考 RFC 4585 [AUTO-TRANSLATED:71241e80]
- // RTP/AVPF: The application scenario is the RTP protocol for video/audio, supporting RTCP-based Feedback. Refer to RFC 4585
- // RTP/SAVPF: 应用场景为视频/音频的 SRTP 协议,支持 RTCP-based Feedback。参考 RFC 5124 [AUTO-TRANSLATED:69015267]
- // RTP/SAVPF: The application scenario is the SRTP protocol for video/audio, supporting RTCP-based Feedback. Refer to RFC 5124
- std::string proto;
- std::vector<std::string> fmts;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "m"; }
- };
- class SdpAttr : public SdpItem {
- public:
- using Ptr = std::shared_ptr<SdpAttr>;
- // 5.13. Attributes ("a=")
- // a=<attribute>
- // a=<attribute>:<value>
- SdpItem::Ptr detail;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const 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.
- std::string type { "BUNDLE" };
- std::vector<std::string> mids;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "group"; }
- };
- class SdpAttrMsidSemantic : public SdpItem {
- public:
- // https://tools.ietf.org/html/draft-alvestrand-rtcweb-msid-02#section-3
- // 3. The Msid-Semantic Attribute
- //
- // In order to fully reproduce the semantics of the SDP and SSRC
- // grouping frameworks, a session-level attribute is defined for
- // signalling the semantics associated with an msid grouping.
- //
- // This OPTIONAL attribute gives the message ID and its group semantic.
- // a=msid-semantic: examplefoo LS
- //
- //
- // The ABNF of msid-semantic is:
- //
- // msid-semantic-attr = "msid-semantic:" " " msid token
- // token = <as defined in RFC 4566>
- //
- // The semantic field may hold values from the IANA registries
- // "Semantics for the "ssrc-group" SDP Attribute" and "Semantics for the
- // "group" SDP Attribute".
- // a=msid-semantic: WMS 616cfbb1-33a3-4d8c-8275-a199d6005549
- std::string msid { "WMS" };
- std::string token;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "msid-semantic"; }
- bool empty() const { return msid.empty(); }
- };
- class SdpAttrRtcp : public SdpItem {
- public:
- // a=rtcp:9 IN IP4 0.0.0.0
- uint16_t port { 0 };
- std::string nettype { "IN" };
- std::string addrtype { "IP4" };
- std::string address { "0.0.0.0" };
- void parse(const std::string &str) override;
- ;
- std::string toString() const override;
- const char *getKey() const override { return "rtcp"; }
- bool empty() const { return address.empty() || !port; }
- };
- class SdpAttrIceUfrag : public SdpItem {
- public:
- SdpAttrIceUfrag() = default;
- SdpAttrIceUfrag(std::string str) { value = std::move(str); }
- // a=ice-ufrag:sXJ3
- const char *getKey() const override { return "ice-ufrag"; }
- };
- class SdpAttrIcePwd : public SdpItem {
- public:
- SdpAttrIcePwd() = default;
- SdpAttrIcePwd(std::string str) { value = std::move(str); }
- // a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV
- const char *getKey() const override { return "ice-pwd"; }
- };
- class SdpAttrIceOption : public SdpItem {
- public:
- // a=ice-options:trickle
- bool trickle { false };
- bool renomination { false };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "ice-options"; }
- };
- 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
- std::string algorithm;
- std::string hash;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "fingerprint"; }
- bool empty() const { return algorithm.empty() || hash.empty(); }
- };
- class SdpAttrSetup : public SdpItem {
- public:
- // a=setup:actpass
- SdpAttrSetup() = default;
- SdpAttrSetup(DtlsRole r) { role = r; }
- DtlsRole role { DtlsRole::actpass };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "setup"; }
- };
- class SdpAttrMid : public SdpItem {
- public:
- SdpAttrMid() = default;
- SdpAttrMid(std::string val) { value = std::move(val); }
- // a=mid:audio
- const char *getKey() const override { return "mid"; }
- };
- class SdpAttrExtmap : public SdpItem {
- public:
- // https://aggresss.blog.csdn.net/article/details/106436703
- // a=extmap:1[/sendonly] urn:ietf:params:rtp-hdrext:ssrc-audio-level
- uint8_t id;
- RtpDirection direction { RtpDirection::invalid };
- std::string ext;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "extmap"; }
- };
- class SdpAttrRtpMap : public SdpItem {
- public:
- // a=rtpmap:111 opus/48000/2
- uint8_t pt;
- std::string codec;
- uint32_t sample_rate;
- uint32_t channel { 0 };
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "rtpmap"; }
- };
- class SdpAttrRtcpFb : public SdpItem {
- public:
- // a=rtcp-fb:98 nack pli
- // a=rtcp-fb:120 nack 支持 nack 重传,nack (Negative-Acknowledgment) 。 [AUTO-TRANSLATED:08d5c4e2]
- // a=rtcp-fb:120 nack supports nack retransmission, nack (Negative-Acknowledgment).
- // a=rtcp-fb:120 nack pli 支持 nack 关键帧重传,PLI (Picture Loss Indication) 。 [AUTO-TRANSLATED:c331c1dd]
- // a=rtcp-fb:120 nack pli supports nack keyframe retransmission, PLI (Picture Loss Indication).
- // a=rtcp-fb:120 ccm fir 支持编码层关键帧请求,CCM (Codec Control Message),FIR (Full Intra Request ),通常与 nack pli 有同样的效果,但是 nack pli [AUTO-TRANSLATED:7090fdc9]
- // a=rtcp-fb:120 ccm fir supports keyframe requests for the coding layer, CCM (Codec Control Message), FIR (Full Intra Request), which usually has the same effect as nack pli, but nack pli
- // 是用于重传时的关键帧请求。 a=rtcp-fb:120 goog-remb 支持 REMB (Receiver Estimated Maximum Bitrate) 。 a=rtcp-fb:120 transport-cc 支持 TCC (Transport [AUTO-TRANSLATED:ffac8e91]
- // is used for keyframe requests during retransmission. a=rtcp-fb:120 goog-remb supports REMB (Receiver Estimated Maximum Bitrate). a=rtcp-fb:120 transport-cc supports TCC (Transport
- // Congest Control) 。 [AUTO-TRANSLATED:dcf53e31]
- // Congest Control).
- uint8_t pt;
- std::string rtcp_type;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "rtcp-fb"; }
- };
- class SdpAttrFmtp : public SdpItem {
- public:
- // fmtp:96 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
- uint8_t pt;
- std::map<std::string /*key*/, std::string /*value*/, StrCaseCompare> fmtp;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "fmtp"; }
- };
- class SdpAttrSSRC : public SdpItem {
- public:
- // a=ssrc:3245185839 cname:Cx4i/VTR51etgjT7
- // a=ssrc:3245185839 msid:cb373bff-0fea-4edb-bc39-e49bb8e8e3b9 0cf7e597-36a2-4480-9796-69bf0955eef5
- // a=ssrc:3245185839 mslabel:cb373bff-0fea-4edb-bc39-e49bb8e8e3b9
- // a=ssrc:3245185839 label:0cf7e597-36a2-4480-9796-69bf0955eef5
- // a=ssrc:<ssrc-id> <attribute>
- // a=ssrc:<ssrc-id> <attribute>:<value>
- // cname 是必须的,msid/mslabel/label 这三个属性都是 WebRTC 自创的,或者说 Google 自创的,可以参考 https://tools.ietf.org/html/draft-ietf-mmusic-msid-17, [AUTO-TRANSLATED:d8cb1baf]
- // cname is required, msid/mslabel/label these three attributes are all created by WebRTC, or Google created, you can refer to https://tools.ietf.org/html/draft-ietf-mmusic-msid-17,
- // 理解它们三者的关系需要先了解三个概念:RTP stream / MediaStreamTrack / MediaStream : [AUTO-TRANSLATED:7d385cf5]
- // understanding the relationship between the three requires understanding three concepts: RTP stream / MediaStreamTrack / MediaStream:
- // 一个 a=ssrc 代表一个 RTP stream ; [AUTO-TRANSLATED:ee1ecc6f]
- // One a=ssrc represents one RTP stream;
- // 一个 MediaStreamTrack 通常包含一个或多个 RTP stream,例如一个视频 MediaStreamTrack 中通常包含两个 RTP stream,一个用于常规传输,一个用于 nack 重传; [AUTO-TRANSLATED:e8ddf0fd]
- // A MediaStreamTrack usually contains one or more RTP streams, for example, a video MediaStreamTrack usually contains two RTP streams, one for regular transmission and one for nack retransmission;
- // 一个 MediaStream 通常包含一个或多个 MediaStreamTrack ,例如 simulcast 场景下,一个 MediaStream 通常会包含三个不同编码质量的 MediaStreamTrack ; [AUTO-TRANSLATED:31318d43]
- // A MediaStream usually contains one or more MediaStreamTrack, for example, in a simulcast scenario, a MediaStream usually contains three MediaStreamTrack of different encoding quality;
- // 这种标记方式并不被 Firefox 认可,在 Firefox 生成的 SDP 中一个 a=ssrc 通常只有一行,例如: [AUTO-TRANSLATED:8c2c424c]
- // This marking method is not recognized by Firefox, in the SDP generated by Firefox, one a=ssrc usually has only one line, for example:
- // a=ssrc:3245185839 cname:Cx4i/VTR51etgjT7
- uint32_t ssrc;
- std::string attribute;
- std::string attribute_value;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "ssrc"; }
- };
- class SdpAttrSSRCGroup : public SdpItem {
- public:
- // a=ssrc-group 定义参考 RFC 5576(https://tools.ietf.org/html/rfc5576) ,用于描述多个 ssrc 之间的关联,常见的有两种: [AUTO-TRANSLATED:a87cbcc6]
- // a=ssrc-group definition refers to RFC 5576(https://tools.ietf.org/html/rfc5576), used to describe the association between multiple ssrcs, there are two common types:
- // a=ssrc-group:FID 2430709021 3715850271
- // FID (Flow Identification) 最初用在 FEC 的关联中,WebRTC 中通常用于关联一组常规 RTP stream 和 重传 RTP stream 。 [AUTO-TRANSLATED:f2c0fcbb]
- // FID (Flow Identification) was originally used in FEC association, and in WebRTC it is usually used to associate a group of regular RTP streams and retransmission RTP streams.
- // a=ssrc-group:SIM 360918977 360918978 360918980
- // 在 Chrome 独有的 SDP munging 风格的 simulcast 中使用,将三组编码质量由低到高的 MediaStreamTrack 关联在一起。 [AUTO-TRANSLATED:61bf7596]
- // Used in Chrome's unique SDP munging style simulcast, associating three groups of MediaStreamTrack from low to high encoding quality.
- std::string type { "FID" };
- std::vector<uint32_t> ssrcs;
- bool isFID() const { return type == "FID"; }
- bool isSIM() const { return type == "SIM"; }
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "ssrc-group"; }
- };
- class SdpAttrSctpMap : public SdpItem {
- public:
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-05
- // a=sctpmap:5000 webrtc-datachannel 1024
- // a=sctpmap: sctpmap-number media-subtypes [streams]
- uint16_t port = 0;
- std::string subtypes;
- uint32_t streams = 0;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "sctpmap"; }
- bool empty() const { return port == 0 && subtypes.empty() && streams == 0; }
- };
- class SdpAttrCandidate : public SdpItem {
- public:
- using Ptr = std::shared_ptr<SdpAttrCandidate>;
- // https://tools.ietf.org/html/rfc5245
- // 15.1. "candidate" Attribute
- // a=candidate:4 1 udp 2 192.168.1.7 58107 typ host
- // a=candidate:<foundation> <component-id> <transport> <priority> <address> <port> typ <cand-type>
- std::string foundation;
- // 传输媒体的类型,1代表RTP;2代表 RTCP。 [AUTO-TRANSLATED:9ec924a6]
- // The type of media to be transmitted, 1 represents RTP; 2 represents RTCP.
- uint32_t component;
- std::string transport { "udp" };
- uint32_t priority;
- std::string address;
- uint16_t port;
- std::string type;
- std::vector<std::pair<std::string, std::string>> arr;
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "candidate"; }
- };
- class SdpAttrMsid : public SdpItem {
- public:
- const char *getKey() const override { return "msid"; }
- };
- class SdpAttrExtmapAllowMixed : public SdpItem {
- public:
- const char *getKey() const override { return "extmap-allow-mixed"; }
- };
- class SdpAttrSimulcast : public SdpItem {
- public:
- // https://www.meetecho.com/blog/simulcast-janus-ssrc/
- // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-14
- const char *getKey() const override { return "simulcast"; }
- void parse(const std::string &str) override;
- std::string toString() const override;
- bool empty() const { return rids.empty(); }
- std::string direction;
- std::vector<std::string> rids;
- };
- class SdpAttrRid : public SdpItem {
- public:
- void parse(const std::string &str) override;
- std::string toString() const override;
- const char *getKey() const override { return "rid"; }
- std::string direction;
- std::string rid;
- };
- class RtcSdpBase {
- public:
- void addItem(SdpItem::Ptr item) { items.push_back(std::move(item)); }
- void addAttr(SdpItem::Ptr attr) {
- auto item = std::make_shared<SdpAttr>();
- item->detail = std::move(attr);
- items.push_back(std::move(item));
- }
- virtual ~RtcSdpBase() = default;
- virtual std::string toString() const;
- void toRtsp();
- RtpDirection getDirection() const;
- template <typename cls>
- cls getItemClass(char key, const char *attr_key = nullptr) const {
- auto item = std::dynamic_pointer_cast<cls>(getItem(key, attr_key));
- if (!item) {
- return cls();
- }
- return *item;
- }
- std::string getStringItem(char key, const char *attr_key = nullptr) const {
- auto item = getItem(key, attr_key);
- if (!item) {
- return "";
- }
- return item->toString();
- }
- SdpItem::Ptr getItem(char key, const char *attr_key = nullptr) const;
- template <typename cls>
- std::vector<cls> getAllItem(char key_c, const char *attr_key = nullptr) const {
- std::vector<cls> ret;
- std::string key(1, key_c);
- for (auto item : items) {
- if (strcasecmp(item->getKey(), key.data()) == 0) {
- if (!attr_key) {
- auto c = std::dynamic_pointer_cast<cls>(item);
- if (c) {
- ret.emplace_back(*c);
- }
- } else {
- auto attr = std::dynamic_pointer_cast<SdpAttr>(item);
- if (attr && !strcasecmp(attr->detail->getKey(), attr_key)) {
- auto c = std::dynamic_pointer_cast<cls>(attr->detail);
- if (c) {
- ret.emplace_back(*c);
- }
- }
- }
- }
- }
- return ret;
- }
- private:
- std::vector<SdpItem::Ptr> items;
- };
- class RtcSessionSdp : public RtcSdpBase {
- public:
- using Ptr = std::shared_ptr<RtcSessionSdp>;
- int getVersion() const;
- SdpOrigin getOrigin() const;
- std::string getSessionName() const;
- std::string getSessionInfo() const;
- SdpTime getSessionTime() const;
- SdpConnection getConnection() const;
- SdpBandwidth getBandwidth() const;
- std::string getUri() const;
- std::string getEmail() const;
- std::string getPhone() const;
- std::string getTimeZone() const;
- std::string getEncryptKey() const;
- std::string getRepeatTimes() const;
- std::vector<RtcSdpBase> medias;
- void parse(const std::string &str);
- std::string toString() const override;
- };
- //////////////////////////////////////////////////////////////////
- // ssrc相关信息 [AUTO-TRANSLATED:954c641d]
- // ssrc related information
- class RtcSSRC {
- public:
- uint32_t ssrc { 0 };
- uint32_t rtx_ssrc { 0 };
- std::string cname;
- std::string msid;
- std::string mslabel;
- std::string label;
- bool empty() const { return ssrc == 0 && cname.empty(); }
- };
- // rtc传输编码方案 [AUTO-TRANSLATED:8b911508]
- // rtc transmission encoding scheme
- class RtcCodecPlan {
- public:
- using Ptr = std::shared_ptr<RtcCodecPlan>;
- uint8_t pt;
- std::string codec;
- uint32_t sample_rate;
- // 音频时有效 [AUTO-TRANSLATED:5b230fc8]
- // Valid for audio
- uint32_t channel = 0;
- // rtcp反馈 [AUTO-TRANSLATED:580378bd]
- // RTCP feedback
- std::set<std::string> rtcp_fb;
- std::map<std::string /*key*/, std::string /*value*/, StrCaseCompare> fmtp;
- std::string getFmtp(const char *key) const;
- };
- // rtc 媒体描述 [AUTO-TRANSLATED:b1711a11]
- // RTC media description
- class RtcMedia {
- public:
- TrackType type { TrackType::TrackInvalid };
- std::string mid;
- uint16_t port { 0 };
- SdpConnection addr;
- SdpBandwidth bandwidth;
- std::string proto;
- RtpDirection direction { RtpDirection::invalid };
- std::vector<RtcCodecPlan> plan;
- //////// rtp ////////
- std::vector<RtcSSRC> rtp_rtx_ssrc;
- //////// simulcast ////////
- std::vector<RtcSSRC> rtp_ssrc_sim;
- std::vector<std::string> rtp_rids;
- //////// rtcp ////////
- bool rtcp_mux { false };
- bool rtcp_rsize { false };
- SdpAttrRtcp rtcp_addr;
- //////// ice ////////
- bool ice_trickle { false };
- bool ice_lite { false };
- bool ice_renomination { false };
- std::string ice_ufrag;
- std::string ice_pwd;
- std::vector<SdpAttrCandidate> candidate;
- //////// dtls ////////
- DtlsRole role { DtlsRole::invalid };
- SdpAttrFingerprint fingerprint;
- //////// extmap ////////
- std::vector<SdpAttrExtmap> extmap;
- //////// sctp ////////////
- SdpAttrSctpMap sctpmap;
- uint32_t sctp_port { 0 };
- void checkValid() const;
- const RtcCodecPlan *getPlan(uint8_t pt) const;
- const RtcCodecPlan *getPlan(const char *codec) const;
- const RtcCodecPlan *getRelatedRtxPlan(uint8_t pt) const;
- uint32_t getRtpSSRC() const;
- uint32_t getRtxSSRC() const;
- bool supportSimulcast() const;
- };
- class RtcSession {
- public:
- using Ptr = std::shared_ptr<RtcSession>;
- uint32_t version;
- SdpOrigin origin;
- std::string session_name;
- std::string session_info;
- SdpTime time;
- SdpConnection connection;
- SdpAttrMsidSemantic msid_semantic;
- std::vector<RtcMedia> media;
- SdpAttrGroup group;
- void loadFrom(const std::string &sdp);
- void checkValid() const;
- std::string toString() const;
- std::string toRtspSdp() const;
- const RtcMedia *getMedia(TrackType type) const;
- bool supportRtcpFb(const std::string &name, TrackType type = TrackType::TrackVideo) const;
- bool supportSimulcast() const;
- bool isOnlyDatachannel() const;
- private:
- RtcSessionSdp::Ptr toRtcSessionSdp() const;
- };
- class RtcConfigure {
- public:
- using Ptr = std::shared_ptr<RtcConfigure>;
- class RtcTrackConfigure {
- public:
- bool rtcp_mux;
- bool rtcp_rsize;
- bool group_bundle;
- bool support_rtx;
- bool support_red;
- bool support_ulpfec;
- bool ice_lite;
- bool ice_trickle;
- bool ice_renomination;
- std::string ice_ufrag;
- std::string ice_pwd;
- RtpDirection direction { RtpDirection::invalid };
- SdpAttrFingerprint fingerprint;
- std::set<std::string> rtcp_fb;
- std::map<RtpExtType, RtpDirection> extmap;
- std::vector<CodecId> preferred_codec;
- std::vector<SdpAttrCandidate> candidate;
- void setDefaultSetting(TrackType type);
- void enableTWCC(bool enable = true);
- void enableREMB(bool enable = true);
- };
- RtcTrackConfigure video;
- RtcTrackConfigure audio;
- RtcTrackConfigure application;
- void setDefaultSetting(std::string ice_ufrag, std::string ice_pwd, RtpDirection direction, const SdpAttrFingerprint &fingerprint);
- void addCandidate(const SdpAttrCandidate &candidate, TrackType type = TrackInvalid);
- std::shared_ptr<RtcSession> createAnswer(const RtcSession &offer) const;
- void setPlayRtspInfo(const std::string &sdp);
- void enableTWCC(bool enable = true, TrackType type = TrackInvalid);
- void enableREMB(bool enable = true, TrackType type = TrackInvalid);
- private:
- void matchMedia(const std::shared_ptr<RtcSession> &ret, const RtcMedia &media) const;
- bool onCheckCodecProfile(const RtcCodecPlan &plan, CodecId codec) const;
- void onSelectPlan(RtcCodecPlan &plan, CodecId codec) const;
- private:
- RtcCodecPlan::Ptr _rtsp_video_plan;
- RtcCodecPlan::Ptr _rtsp_audio_plan;
- };
- class SdpConst {
- public:
- static std::string const kTWCCRtcpFb;
- static std::string const kRembRtcpFb;
- private:
- SdpConst() = delete;
- ~SdpConst() = delete;
- };
- } // namespace mediakit
- #endif // ZLMEDIAKIT_SDP_H
|