mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 11:51:57 +00:00
RTC: Support offer by server
This commit is contained in:
parent
f33a62e3bd
commit
52a3f36b39
5 changed files with 151 additions and 36 deletions
|
@ -242,16 +242,18 @@ srs_error_t SrsRtcPlayStream::initialize(SrsRequest* req, std::map<uint32_t, Srs
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::map<uint32_t, SrsRtcTrackDescription*>::iterator it = sub_relations.begin();
|
||||
while (it != sub_relations.end()) {
|
||||
if (it->second->type_ == "audio") {
|
||||
audio_tracks_.insert(make_pair(it->first, new SrsRtcAudioSendTrack(session_, it->second)));
|
||||
}
|
||||
if (true) {
|
||||
std::map<uint32_t, SrsRtcTrackDescription*>::iterator it = sub_relations.begin();
|
||||
while (it != sub_relations.end()) {
|
||||
if (it->second->type_ == "audio") {
|
||||
audio_tracks_.insert(make_pair(it->first, new SrsRtcAudioSendTrack(session_, it->second)));
|
||||
}
|
||||
|
||||
if (it->second->type_ == "video") {
|
||||
video_tracks_.insert(make_pair(it->first, new SrsRtcVideoSendTrack(session_, it->second)));
|
||||
if (it->second->type_ == "video") {
|
||||
video_tracks_.insert(make_pair(it->first, new SrsRtcVideoSendTrack(session_, it->second)));
|
||||
}
|
||||
++it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
// TODO: FIXME: Support reload.
|
||||
|
@ -500,6 +502,14 @@ srs_error_t SrsRtcPlayStream::do_send_packets(const std::vector<SrsRtpPacket2*>&
|
|||
|
||||
// Marshal packet to bytes in iovec.
|
||||
if (true) {
|
||||
#ifdef SRS_CXX14
|
||||
// should set twcc sn before packet encode.
|
||||
if(twcc_id_) {
|
||||
twcc_sn = twcc_controller.allocate_twcc_sn();
|
||||
pkt->header.set_twcc_sequence_number(twcc_id_, twcc_sn);
|
||||
}
|
||||
#endif
|
||||
|
||||
SrsBuffer stream((char*)iov->iov_base, iov->iov_len);
|
||||
if ((err = pkt->encode(&stream)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode packet");
|
||||
|
@ -546,7 +556,9 @@ void SrsRtcPlayStream::nack_fetch(vector<SrsRtpPacket2*>& pkts, uint32_t ssrc, u
|
|||
for (it = audio_tracks_.begin(); it != audio_tracks_.end(); ++it) {
|
||||
if (it->second->has_ssrc(ssrc)) {
|
||||
SrsRtpPacket2* pkt = it->second->fetch_rtp_packet(seq);
|
||||
pkts.push_back(pkt);
|
||||
if (pkt != NULL) {
|
||||
pkts.push_back(pkt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +569,9 @@ void SrsRtcPlayStream::nack_fetch(vector<SrsRtpPacket2*>& pkts, uint32_t ssrc, u
|
|||
for (it = video_tracks_.begin(); it != video_tracks_.end(); ++it) {
|
||||
if (it->second->has_ssrc(ssrc)) {
|
||||
SrsRtpPacket2* pkt = it->second->fetch_rtp_packet(seq);
|
||||
pkts.push_back(pkt);
|
||||
if (pkt != NULL) {
|
||||
pkts.push_back(pkt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -854,12 +868,16 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcStreamDescripti
|
|||
|
||||
int twcc_id = -1;
|
||||
uint32_t media_ssrc = 0;
|
||||
if (stream_desc->audio_track_desc_) {
|
||||
SrsRtcTrackDescription* desc = stream_desc->audio_track_desc_;
|
||||
// because audio_track_desc have not twcc id, for example, h5demo
|
||||
// fetch twcc_id from video track description,
|
||||
for (int i = 0; i < stream_desc->video_track_descs_.size(); ++i) {
|
||||
SrsRtcTrackDescription* desc = stream_desc->video_track_descs_.at(i);
|
||||
twcc_id = desc->get_rtp_extension_id(kTWCCExt);
|
||||
media_ssrc = desc->ssrc_;
|
||||
break;
|
||||
}
|
||||
if (twcc_id != -1) {
|
||||
twcc_id_ = twcc_id;
|
||||
extension_types_.register_by_uri(twcc_id_, kTWCCExt);
|
||||
rtcp_twcc_.set_media_ssrc(media_ssrc);
|
||||
}
|
||||
|
@ -1703,6 +1721,45 @@ srs_error_t SrsRtcConnection::add_player(SrsRequest* req, const SrsSdp& remote_s
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::add_player2(SrsRequest* req, SrsSdp& local_sdp)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::map<uint32_t, SrsRtcTrackDescription*> play_sub_relations;
|
||||
if ((err = fetch_source_capability(req, play_sub_relations)) != srs_success) {
|
||||
return srs_error_wrap(err, "remote sdp have error or unsupport attributes");
|
||||
}
|
||||
|
||||
if (!play_sub_relations.size()) {
|
||||
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "cannot negotiate sub relations");
|
||||
}
|
||||
|
||||
SrsRtcStreamDescription* stream_desc = new SrsRtcStreamDescription();
|
||||
SrsAutoFree(SrsRtcStreamDescription, stream_desc);
|
||||
|
||||
std::map<uint32_t, SrsRtcTrackDescription*>::iterator it = play_sub_relations.begin();
|
||||
while (it != play_sub_relations.end()) {
|
||||
if (it->second->type_ == "audio" || !stream_desc->audio_track_desc_) {
|
||||
stream_desc->audio_track_desc_ = it->second->copy();
|
||||
}
|
||||
|
||||
if (it->second->type_ == "video") {
|
||||
stream_desc->video_track_descs_.push_back(it->second->copy());
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
if ((err = generate_play_local_sdp(req, local_sdp, stream_desc)) != srs_success) {
|
||||
return srs_error_wrap(err, "generate local sdp");
|
||||
}
|
||||
|
||||
if ((err = create_player(req, play_sub_relations)) != srs_success) {
|
||||
return srs_error_wrap(err, "create player");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::initialize(SrsRtcStream* source, SrsRequest* r, bool is_publisher, string username, SrsContextId context_id)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -2517,25 +2574,19 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S
|
|||
// TODO: FIXME: if we support downlink RTX, MUST assign rtx_ssrc_, rtx_pt, rtx_apt
|
||||
// not support rtx
|
||||
if (true) {
|
||||
if (track->rtx_) {
|
||||
srs_freep(track->rtx_);
|
||||
}
|
||||
srs_freep(track->rtx_);
|
||||
track->rtx_ssrc_ = 0;
|
||||
}
|
||||
// TODO: FIXME: if we support downlink ulpfec, MUST assign ulpfec params
|
||||
// set_ulpfec_config;
|
||||
if (true) {
|
||||
if (track->ulpfec_) {
|
||||
srs_freep(track->ulpfec_);
|
||||
}
|
||||
srs_freep(track->ulpfec_);
|
||||
track->fec_ssrc_ = 0;
|
||||
}
|
||||
// TODO: FIXME: if we support downlink , MUST assign fec_ssrc_
|
||||
// set_rsfec_config;
|
||||
if (true) {
|
||||
if (track->rsfec_) {
|
||||
srs_freep(track->rsfec_);
|
||||
}
|
||||
srs_freep(track->rsfec_);
|
||||
track->fec_ssrc_ = 0;
|
||||
}
|
||||
|
||||
|
@ -2547,6 +2598,69 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::fetch_source_capability(SrsRequest* req, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
bool nack_enabled = _srs_config->get_rtc_nack_enabled(req->vhost);
|
||||
bool twcc_enabled = _srs_config->get_rtc_twcc_enabled(req->vhost);
|
||||
|
||||
SrsRtcStream* source = NULL;
|
||||
if ((err = _srs_rtc_sources->fetch_or_create(req, &source)) != srs_success) {
|
||||
return srs_error_wrap(err, "fetch rtc source");
|
||||
}
|
||||
|
||||
// TODO: FIXME: Avoid SSRC collision.
|
||||
if (!ssrc_num) {
|
||||
ssrc_num = ::getpid() * 10000 + ::getpid() * 100 + ::getpid();
|
||||
}
|
||||
|
||||
std::vector<SrsRtcTrackDescription*> track_descs = source->get_track_desc("audio", "opus");
|
||||
std::vector<SrsRtcTrackDescription*> video_track_desc = source->get_track_desc("video", "H264");
|
||||
|
||||
track_descs.insert(track_descs.end(), video_track_desc.begin(), video_track_desc.end());
|
||||
for (int i = 0; i < track_descs.size(); ++i) {
|
||||
SrsRtcTrackDescription* track = track_descs[i]->copy();
|
||||
uint32_t publish_ssrc = track->ssrc_;
|
||||
|
||||
track->media_->rtcp_fbs_.clear();
|
||||
if (nack_enabled) {
|
||||
track->media_->rtcp_fbs_.push_back("nack");
|
||||
track->media_->rtcp_fbs_.push_back("nack pli");
|
||||
}
|
||||
|
||||
int local_twcc_id = track->get_rtp_extension_id(kTWCCExt);
|
||||
track->extmaps_.clear();
|
||||
if (twcc_enabled && local_twcc_id) {
|
||||
track->media_->rtcp_fbs_.push_back("transport-cc");
|
||||
track->add_rtp_extension_desc(local_twcc_id, kTWCCExt);
|
||||
}
|
||||
|
||||
track->ssrc_ = ++ssrc_num;
|
||||
// TODO: FIXME: set audio_payload rtcp_fbs_,
|
||||
// according by whether downlink is support transport algorithms.
|
||||
// TODO: FIXME: if we support downlink RTX, MUST assign rtx_ssrc_, rtx_pt, rtx_apt
|
||||
// not support rtx
|
||||
srs_freep(track->rtx_);
|
||||
track->rtx_ssrc_ = 0;
|
||||
|
||||
// TODO: FIXME: if we support downlink ulpfec, MUST assign ulpfec params
|
||||
// set_ulpfec_config;
|
||||
srs_freep(track->ulpfec_);
|
||||
track->fec_ssrc_ = 0;
|
||||
|
||||
// TODO: FIXME: if we support downlink , MUST assign fec_ssrc_
|
||||
// set_rsfec_config;
|
||||
srs_freep(track->rsfec_);
|
||||
track->fec_ssrc_ = 0;
|
||||
|
||||
track->set_direction("sendonly");
|
||||
sub_relations.insert(make_pair(publish_ssrc, track));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcStreamDescription* stream_desc)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -2586,9 +2700,6 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& l
|
|||
local_media_desc.rtcp_mux_ = true;
|
||||
local_media_desc.rtcp_rsize_ = true;
|
||||
|
||||
local_media_desc.mid_ = audio_track->mid_;
|
||||
local_media_desc.msid_ = stream_id;
|
||||
local_media_desc.msid_tracker_ = audio_track->id_;
|
||||
local_media_desc.extmaps_ = audio_track->extmaps_;
|
||||
|
||||
local_media_desc.mid_ = audio_track->mid_;
|
||||
|
@ -2610,7 +2721,6 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& l
|
|||
//TODO: FIXME: add red, rtx, ulpfec, rsfec..., payload_types_.
|
||||
//local_media_desc.payload_types_.push_back(payload->generate_media_payload_type());
|
||||
|
||||
|
||||
local_media_desc.ssrc_infos_.push_back(SrsSSRCInfo(audio_track->ssrc_, cname, stream_id, audio_track->id_));
|
||||
|
||||
if (audio_track->rtx_) {
|
||||
|
@ -2645,9 +2755,6 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& l
|
|||
local_media_desc.rtcp_mux_ = true;
|
||||
local_media_desc.rtcp_rsize_ = true;
|
||||
|
||||
local_media_desc.mid_ = track->mid_;
|
||||
local_media_desc.msid_ = stream_id;
|
||||
local_media_desc.msid_tracker_ = track->id_;
|
||||
local_media_desc.extmaps_ = track->extmaps_;
|
||||
|
||||
local_media_desc.mid_ = track->mid_;
|
||||
|
@ -2688,8 +2795,6 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& l
|
|||
|
||||
local_media_desc.ssrc_infos_.push_back(SrsSSRCInfo(track->fec_ssrc_, cname, stream_id, track->id_));
|
||||
}
|
||||
// only need media desc info, not ssrc info;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -358,6 +358,8 @@ public:
|
|||
SrsContextId context_id();
|
||||
srs_error_t add_publisher(SrsRequest* request, const SrsSdp& remote_sdp, SrsSdp& local_sdp);
|
||||
srs_error_t add_player(SrsRequest* request, const SrsSdp& remote_sdp, SrsSdp& local_sdp);
|
||||
// server send offer sdp to client, local sdp derivate from source stream desc.
|
||||
srs_error_t add_player2(SrsRequest* request, SrsSdp& local_sdp);
|
||||
public:
|
||||
// Before initialize, user must set the local SDP, which is used to inititlize DTLS.
|
||||
srs_error_t initialize(SrsRtcStream* source, SrsRequest* r, bool is_publisher, std::string username, SrsContextId context_id);
|
||||
|
@ -388,6 +390,7 @@ private:
|
|||
srs_error_t generate_publish_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcStreamDescription* stream_desc);
|
||||
// play media capabilitiy negotiate
|
||||
srs_error_t negotiate_play_capability(SrsRequest* req, const SrsSdp& remote_sdp, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations);
|
||||
srs_error_t fetch_source_capability(SrsRequest* req, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations);
|
||||
srs_error_t generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcStreamDescription* stream_desc);
|
||||
srs_error_t create_player(SrsRequest* request, std::map<uint32_t, SrsRtcTrackDescription*> sub_relations);
|
||||
srs_error_t create_publisher(SrsRequest* request, SrsRtcStreamDescription* stream_desc);
|
||||
|
|
|
@ -337,7 +337,7 @@ srs_error_t SrsRtcServer::do_create_session(
|
|||
}
|
||||
} else {
|
||||
if ((err = session->add_player(req, remote_sdp, local_sdp)) != srs_success) {
|
||||
return srs_error_wrap(err, "add publisher");
|
||||
return srs_error_wrap(err, "add player");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ srs_error_t SrsRtcServer::do_create_session(
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcServer::create_session2(SrsSdp& local_sdp, SrsRtcConnection** psession)
|
||||
srs_error_t SrsRtcServer::create_session2(SrsRequest* req, SrsSdp& local_sdp, SrsRtcConnection** psession)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -406,8 +406,14 @@ srs_error_t SrsRtcServer::create_session2(SrsSdp& local_sdp, SrsRtcConnection**
|
|||
std::string local_ufrag = srs_random_str(8);
|
||||
|
||||
SrsRtcConnection* session = new SrsRtcConnection(this);
|
||||
// first add player for negotiate local sdp media info
|
||||
if ((err = session->add_player2(req, local_sdp)) != srs_success) {
|
||||
srs_freep(session);
|
||||
return srs_error_wrap(err, "add player2");
|
||||
}
|
||||
*psession = session;
|
||||
|
||||
local_sdp.set_dtls_role("actpass");
|
||||
local_sdp.set_ice_ufrag(local_ufrag);
|
||||
local_sdp.set_ice_pwd(local_pwd);
|
||||
local_sdp.set_fingerprint_algo("sha-256");
|
||||
|
|
|
@ -88,7 +88,7 @@ private:
|
|||
);
|
||||
public:
|
||||
// We start offering, create_session2 to generate offer, setup_session2 to handle answer.
|
||||
srs_error_t create_session2(SrsSdp& local_sdp, SrsRtcConnection** psession);
|
||||
srs_error_t create_session2(SrsRequest* req, SrsSdp& local_sdp, SrsRtcConnection** psession);
|
||||
srs_error_t setup_session2(SrsRtcConnection* session, SrsRequest* req, const SrsSdp& remote_sdp);
|
||||
// Destroy the session from server.
|
||||
void destroy(SrsRtcConnection* session);
|
||||
|
|
|
@ -1207,7 +1207,9 @@ SrsMediaPayloadType SrsAudioPayload::generate_media_payload_type()
|
|||
|
||||
media_payload_type.encoding_name_ = name_;
|
||||
media_payload_type.clock_rate_ = sample_;
|
||||
media_payload_type.encoding_param_ = srs_int2str(channel_);
|
||||
if (channel_ != 0) {
|
||||
media_payload_type.encoding_param_ = srs_int2str(channel_);
|
||||
}
|
||||
media_payload_type.rtcp_fb_ = rtcp_fbs_;
|
||||
|
||||
std::ostringstream format_specific_param;
|
||||
|
@ -1220,7 +1222,6 @@ SrsMediaPayloadType SrsAudioPayload::generate_media_payload_type()
|
|||
if (opus_param_.usedtx) {
|
||||
format_specific_param << ";usedtx=1";
|
||||
}
|
||||
|
||||
media_payload_type.format_specific_param_ = format_specific_param.str();
|
||||
|
||||
return media_payload_type;
|
||||
|
@ -1339,7 +1340,7 @@ int SrsRtcTrackDescription::get_rtp_extension_id(std::string uri)
|
|||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SrsRtcTrackDescription* SrsRtcTrackDescription::copy()
|
||||
|
|
Loading…
Reference in a new issue