RTC: Support offer by server

pull/1908/head
winlin 5 years ago
parent f33a62e3bd
commit 52a3f36b39

@ -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…
Cancel
Save