1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

RTC: Fix rtmp to rtc bug

This commit is contained in:
winlin 2020-07-19 10:26:05 +08:00
parent 7ad1dfbbb8
commit 6dd77923ca
3 changed files with 119 additions and 22 deletions

View file

@ -1554,8 +1554,6 @@ void SrsRtcPublishStream::update_send_report_time(uint32_t ssrc, const SrsNtp& n
} }
} }
uint32_t SrsRtcConnection::ssrc_num = 0;
SrsRtcConnection::SrsRtcConnection(SrsRtcServer* s) SrsRtcConnection::SrsRtcConnection(SrsRtcServer* s)
{ {
req = NULL; req = NULL;
@ -2516,11 +2514,6 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S
return srs_error_wrap(err, "fetch rtc source"); return srs_error_wrap(err, "fetch rtc source");
} }
// TODO: FIXME: Avoid SSRC collision.
if (!ssrc_num) {
ssrc_num = ::getpid() * 10000 + ::getpid() * 100 + ::getpid();
}
for (size_t i = 0; i < remote_sdp.media_descs_.size(); ++i) { for (size_t i = 0; i < remote_sdp.media_descs_.size(); ++i) {
const SrsMediaDesc& remote_media_desc = remote_sdp.media_descs_[i]; const SrsMediaDesc& remote_media_desc = remote_sdp.media_descs_[i];
// Whether feature enabled in remote extmap. // Whether feature enabled in remote extmap.
@ -2536,12 +2529,17 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S
} }
std::vector<SrsRtcTrackDescription*> track_descs; std::vector<SrsRtcTrackDescription*> track_descs;
std::vector<std::string> remote_rtcp_fb;
if (remote_media_desc.is_audio()) { if (remote_media_desc.is_audio()) {
// TODO: check opus format specific param // TODO: check opus format specific param
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("opus"); std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("opus");
if (payloads.empty()) { if (payloads.empty()) {
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type"); return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type");
} }
SrsMediaPayloadType payload = payloads.at(0);
remote_rtcp_fb = payload.rtcp_fb_;
track_descs = source->get_track_desc("audio", "opus"); track_descs = source->get_track_desc("audio", "opus");
} else if (remote_media_desc.is_video()) { } else if (remote_media_desc.is_video()) {
// TODO: check opus format specific param // TODO: check opus format specific param
@ -2549,25 +2547,34 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRequest* req, const S
if (payloads.empty()) { if (payloads.empty()) {
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type"); return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no valid found opus payload type");
} }
SrsMediaPayloadType payload = payloads.at(0);
remote_rtcp_fb = payload.rtcp_fb_;
track_descs = source->get_track_desc("video", "H264"); track_descs = source->get_track_desc("video", "H264");
} }
for (int i = 0; i < track_descs.size(); ++i) { for (int i = 0; i < track_descs.size(); ++i) {
SrsRtcTrackDescription* track = track_descs[i]->copy(); SrsRtcTrackDescription* track = track_descs[i]->copy();
track->mid_ = remote_media_desc.mid_;
uint32_t publish_ssrc = track->ssrc_; uint32_t publish_ssrc = track->ssrc_;
track->media_->rtcp_fbs_.clear(); track->media_->rtcp_fbs_.clear();
track->extmaps_.clear();
for (int j = 0; j < (int)remote_rtcp_fb.size(); j++) {
if (nack_enabled) { if (nack_enabled) {
track->media_->rtcp_fbs_.push_back("nack"); if (remote_rtcp_fb.at(j) == "nack" || remote_rtcp_fb.at(j) == "nack pli" || remote_rtcp_fb.at(j) == "transport-cc") {
track->media_->rtcp_fbs_.push_back("nack pli"); track->media_->rtcp_fbs_.push_back(remote_rtcp_fb.at(j));
}
}
} }
track->extmaps_.clear();
if (twcc_enabled && remote_twcc_id) { if (twcc_enabled && remote_twcc_id) {
track->add_rtp_extension_desc(remote_twcc_id, kTWCCExt); track->add_rtp_extension_desc(remote_twcc_id, kTWCCExt);
} }
track->ssrc_ = ++ssrc_num; track->ssrc_ = SrsRtcSSRCGenerator::instance()->generate_ssrc();
// TODO: FIXME: set audio_payload rtcp_fbs_, // TODO: FIXME: set audio_payload rtcp_fbs_,
// according by whether downlink is support transport algorithms. // according by whether downlink is support transport algorithms.
// TODO: FIXME: if we support downlink RTX, MUST assign rtx_ssrc_, rtx_pt, rtx_apt // TODO: FIXME: if we support downlink RTX, MUST assign rtx_ssrc_, rtx_pt, rtx_apt
@ -2603,11 +2610,6 @@ srs_error_t SrsRtcConnection::fetch_source_capability(SrsRequest* req, std::map<
return srs_error_wrap(err, "fetch rtc source"); 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*> track_descs = source->get_track_desc("audio", "opus");
std::vector<SrsRtcTrackDescription*> video_track_desc = source->get_track_desc("video", "H264"); std::vector<SrsRtcTrackDescription*> video_track_desc = source->get_track_desc("video", "H264");
@ -2629,7 +2631,7 @@ srs_error_t SrsRtcConnection::fetch_source_capability(SrsRequest* req, std::map<
track->add_rtp_extension_desc(local_twcc_id, kTWCCExt); track->add_rtp_extension_desc(local_twcc_id, kTWCCExt);
} }
track->ssrc_ = ++ssrc_num; track->ssrc_ = SrsRtcSSRCGenerator::instance()->generate_ssrc();
// TODO: FIXME: set audio_payload rtcp_fbs_, // TODO: FIXME: set audio_payload rtcp_fbs_,
// according by whether downlink is support transport algorithms. // according by whether downlink is support transport algorithms.
// TODO: FIXME: if we support downlink RTX, MUST assign rtx_ssrc_, rtx_pt, rtx_apt // TODO: FIXME: if we support downlink RTX, MUST assign rtx_ssrc_, rtx_pt, rtx_apt

View file

@ -23,6 +23,8 @@
#include <srs_app_rtc_source.hpp> #include <srs_app_rtc_source.hpp>
#include <unistd.h>
#include <srs_app_conn.hpp> #include <srs_app_conn.hpp>
#include <srs_rtmp_stack.hpp> #include <srs_rtmp_stack.hpp>
#include <srs_app_config.hpp> #include <srs_app_config.hpp>
@ -37,13 +39,18 @@
#include <srs_core_autofree.hpp> #include <srs_core_autofree.hpp>
#include <srs_app_rtc_queue.hpp> #include <srs_app_rtc_queue.hpp>
#include <srs_app_rtc_conn.hpp> #include <srs_app_rtc_conn.hpp>
#include <srs_protocol_utility.hpp>
#ifdef SRS_FFMPEG_FIT #ifdef SRS_FFMPEG_FIT
#include <srs_app_rtc_codec.hpp> #include <srs_app_rtc_codec.hpp>
#endif #endif
const int kChannel = 2; const int kAudioPayloadType = 111;
const int kSamplerate = 48000; const int kAudioChannel = 2;
const int kAudioSamplerate = 48000;
const int kVideoPayloadType = 102;
const int kVideoSamplerate = 90000;
// An AAC packet may be transcoded to many OPUS packets. // An AAC packet may be transcoded to many OPUS packets.
const int kMaxOpusPackets = 8; const int kMaxOpusPackets = 8;
@ -284,6 +291,7 @@ SrsRtcStream::SrsRtcStream()
{ {
_can_publish = true; _can_publish = true;
publish_stream_ = NULL; publish_stream_ = NULL;
stream_desc_ = NULL;
req = NULL; req = NULL;
#ifdef SRS_FFMPEG_FIT #ifdef SRS_FFMPEG_FIT
@ -291,7 +299,6 @@ SrsRtcStream::SrsRtcStream()
#else #else
bridger_ = new SrsRtcDummyBridger(); bridger_ = new SrsRtcDummyBridger();
#endif #endif
stream_desc_ = NULL;
} }
SrsRtcStream::~SrsRtcStream() SrsRtcStream::~SrsRtcStream()
@ -498,7 +505,7 @@ SrsRtcFromRtmpBridger::SrsRtcFromRtmpBridger(SrsRtcStream* source)
req = NULL; req = NULL;
source_ = source; source_ = source;
format = new SrsRtmpFormat(); format = new SrsRtmpFormat();
codec = new SrsAudioRecode(kChannel, kSamplerate); codec = new SrsAudioRecode(kAudioChannel, kAudioSamplerate);
discard_aac = false; discard_aac = false;
discard_bframe = false; discard_bframe = false;
merge_nalus = false; merge_nalus = false;
@ -506,6 +513,39 @@ SrsRtcFromRtmpBridger::SrsRtcFromRtmpBridger(SrsRtcStream* source)
audio_timestamp = 0; audio_timestamp = 0;
audio_sequence = 0; audio_sequence = 0;
video_sequence = 0; video_sequence = 0;
SrsRtcStreamDescription* stream_desc = new SrsRtcStreamDescription();
SrsAutoFree(SrsRtcStreamDescription, stream_desc);
// audio track description
if (true) {
SrsRtcTrackDescription* audio_track_desc = new SrsRtcTrackDescription();
audio_track_desc->type_ = "audio";
audio_track_desc->id_ = "audio-" + srs_random_str(8);
audio_ssrc = SrsRtcSSRCGenerator::instance()->generate_ssrc();
audio_track_desc->ssrc_ = audio_ssrc;
audio_track_desc->direction_ = "recvonly";
audio_track_desc->media_ = new SrsAudioPayload(kAudioPayloadType, "opus", kAudioSamplerate, kAudioChannel);
stream_desc->audio_track_desc_ = audio_track_desc->copy();
}
// video track description
if (true) {
SrsRtcTrackDescription* video_track_desc = new SrsRtcTrackDescription();
video_track_desc->type_ = "video";
video_track_desc->id_ = "video-" + srs_random_str(8);
video_ssrc = SrsRtcSSRCGenerator::instance()->generate_ssrc();
video_track_desc->ssrc_ = video_ssrc;
video_track_desc->direction_ = "recvonly";
video_track_desc->media_ = new SrsVideoPayload(kVideoPayloadType, "H264", kVideoSamplerate);
stream_desc->video_track_descs_.push_back(video_track_desc->copy());
}
source_->set_stream_desc(stream_desc);
} }
SrsRtcFromRtmpBridger::~SrsRtcFromRtmpBridger() SrsRtcFromRtmpBridger::~SrsRtcFromRtmpBridger()
@ -672,6 +712,8 @@ srs_error_t SrsRtcFromRtmpBridger::package_opus(char* data, int size, SrsRtpPack
srs_error_t err = srs_success; srs_error_t err = srs_success;
SrsRtpPacket2* pkt = new SrsRtpPacket2(); SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->header.set_payload_type(kAudioPayloadType);
pkt->header.set_ssrc(audio_ssrc);
pkt->frame_type = SrsFrameTypeAudio; pkt->frame_type = SrsFrameTypeAudio;
pkt->header.set_marker(true); pkt->header.set_marker(true);
pkt->header.set_sequence(audio_sequence++); pkt->header.set_sequence(audio_sequence++);
@ -813,6 +855,8 @@ srs_error_t SrsRtcFromRtmpBridger::package_stap_a(SrsRtcStream* source, SrsShare
} }
SrsRtpPacket2* pkt = new SrsRtpPacket2(); SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->header.set_payload_type(kVideoPayloadType);
pkt->header.set_ssrc(video_ssrc);
pkt->frame_type = SrsFrameTypeVideo; pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_marker(false); pkt->header.set_marker(false);
pkt->header.set_sequence(video_sequence++); pkt->header.set_sequence(video_sequence++);
@ -884,6 +928,8 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
if (nn_bytes < kRtpMaxPayloadSize) { if (nn_bytes < kRtpMaxPayloadSize) {
// Package NALUs in a single RTP packet. // Package NALUs in a single RTP packet.
SrsRtpPacket2* pkt = new SrsRtpPacket2(); SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->header.set_payload_type(kVideoPayloadType);
pkt->header.set_ssrc(video_ssrc);
pkt->frame_type = SrsFrameTypeVideo; pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++); pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90); pkt->header.set_timestamp(msg->timestamp * 90);
@ -914,6 +960,8 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
} }
SrsRtpPacket2* pkt = new SrsRtpPacket2(); SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->header.set_payload_type(kVideoPayloadType);
pkt->header.set_ssrc(video_ssrc);
pkt->frame_type = SrsFrameTypeVideo; pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++); pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90); pkt->header.set_timestamp(msg->timestamp * 90);
@ -940,6 +988,8 @@ srs_error_t SrsRtcFromRtmpBridger::package_single_nalu(SrsSharedPtrMessage* msg,
srs_error_t err = srs_success; srs_error_t err = srs_success;
SrsRtpPacket2* pkt = new SrsRtpPacket2(); SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->header.set_payload_type(kVideoPayloadType);
pkt->header.set_ssrc(video_ssrc);
pkt->frame_type = SrsFrameTypeVideo; pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++); pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90); pkt->header.set_timestamp(msg->timestamp * 90);
@ -970,6 +1020,8 @@ srs_error_t SrsRtcFromRtmpBridger::package_fu_a(SrsSharedPtrMessage* msg, SrsSam
int packet_size = srs_min(nb_left, fu_payload_size); int packet_size = srs_min(nb_left, fu_payload_size);
SrsRtpPacket2* pkt = new SrsRtpPacket2(); SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->header.set_payload_type(kVideoPayloadType);
pkt->header.set_ssrc(video_ssrc);
pkt->frame_type = SrsFrameTypeVideo; pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++); pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90); pkt->header.set_timestamp(msg->timestamp * 90);
@ -1700,3 +1752,30 @@ srs_error_t SrsRtcVideoSendTrack::on_rtcp(SrsRtpPacket2* pkt)
return err; return err;
} }
SrsRtcSSRCGenerator* SrsRtcSSRCGenerator::_instance = NULL;
SrsRtcSSRCGenerator::SrsRtcSSRCGenerator()
{
ssrc_num = 0;
}
SrsRtcSSRCGenerator::~SrsRtcSSRCGenerator()
{
}
SrsRtcSSRCGenerator* SrsRtcSSRCGenerator::instance()
{
if (!_instance) {
_instance = new SrsRtcSSRCGenerator();
}
return _instance;
}
uint32_t SrsRtcSSRCGenerator::generate_ssrc()
{
if (!ssrc_num) {
ssrc_num = ::getpid() * 10000 + ::getpid() * 100 + ::getpid();
}
return ++ssrc_num;
}

View file

@ -211,6 +211,8 @@ private:
uint32_t audio_timestamp; uint32_t audio_timestamp;
uint16_t audio_sequence; uint16_t audio_sequence;
uint16_t video_sequence; uint16_t video_sequence;
uint32_t audio_ssrc;
uint32_t video_ssrc;
public: public:
SrsRtcFromRtmpBridger(SrsRtcStream* source); SrsRtcFromRtmpBridger(SrsRtcStream* source);
virtual ~SrsRtcFromRtmpBridger(); virtual ~SrsRtcFromRtmpBridger();
@ -473,5 +475,19 @@ public:
virtual srs_error_t on_rtcp(SrsRtpPacket2* pkt); virtual srs_error_t on_rtcp(SrsRtpPacket2* pkt);
}; };
class SrsRtcSSRCGenerator
{
private:
static SrsRtcSSRCGenerator* _instance;
private:
uint32_t ssrc_num;
private:
SrsRtcSSRCGenerator();
virtual ~SrsRtcSSRCGenerator();
public:
static SrsRtcSSRCGenerator* instance();
uint32_t generate_ssrc();
};
#endif #endif