diff --git a/erizo/src/erizo/MediaDefinitions.h b/erizo/src/erizo/MediaDefinitions.h index 2c3bf2abdd..4cb5a210c6 100644 --- a/erizo/src/erizo/MediaDefinitions.h +++ b/erizo/src/erizo/MediaDefinitions.h @@ -102,7 +102,7 @@ class FeedbackSink { public: virtual ~FeedbackSink() {} int deliverFeedback(std::shared_ptr data_packet) { - return this->deliverFeedback_(data_packet); + return deliverFeedback_(data_packet); } private: virtual int deliverFeedback_(std::shared_ptr data_packet) = 0; @@ -110,13 +110,13 @@ class FeedbackSink { class FeedbackSource { protected: - FeedbackSink* fb_sink_; + std::weak_ptr fb_sink_; public: - FeedbackSource(): fb_sink_{nullptr} {} - virtual ~FeedbackSource() {} - void setFeedbackSink(FeedbackSink* sink) { - fb_sink_ = sink; - } + FeedbackSource() : fb_sink_{} {} + virtual ~FeedbackSource() {} + void setFeedbackSink(std::weak_ptr sink) { + fb_sink_ = sink; + } }; /* @@ -128,14 +128,14 @@ class MediaSink: public virtual Monitor { uint32_t audio_sink_ssrc_; uint32_t video_sink_ssrc_; // Is it able to provide Feedback - FeedbackSource* sink_fb_source_; + std::weak_ptr sink_fb_source_; public: int deliverAudioData(std::shared_ptr data_packet) { - return this->deliverAudioData_(data_packet); + return deliverAudioData_(data_packet); } int deliverVideoData(std::shared_ptr data_packet) { - return this->deliverVideoData_(data_packet); + return deliverVideoData_(data_packet); } uint32_t getVideoSinkSSRC() { boost::mutex::scoped_lock lock(monitor_mutex_); @@ -159,14 +159,14 @@ class MediaSink: public virtual Monitor { bool isAudioSinkSSRC(uint32_t ssrc) { return ssrc == audio_sink_ssrc_; } - FeedbackSource* getFeedbackSource() { + std::weak_ptr getFeedbackSource() { boost::mutex::scoped_lock lock(monitor_mutex_); return sink_fb_source_; } int deliverEvent(MediaEventPtr event) { - return this->deliverEvent_(event); + return deliverEvent_(event); } - MediaSink() : audio_sink_ssrc_{0}, video_sink_ssrc_{0}, sink_fb_source_{nullptr} {} + MediaSink() : audio_sink_ssrc_{0}, video_sink_ssrc_{0}, sink_fb_source_{} {} virtual ~MediaSink() {} virtual boost::future close() = 0; @@ -185,29 +185,29 @@ class MediaSource: public virtual Monitor { // SSRCs coming from the source uint32_t audio_source_ssrc_; std::vector video_source_ssrc_list_; - MediaSink* video_sink_; - MediaSink* audio_sink_; - MediaSink* event_sink_; + std::weak_ptr video_sink_; + std::weak_ptr audio_sink_; + std::weak_ptr event_sink_; // can it accept feedback - FeedbackSink* source_fb_sink_; + std::weak_ptr source_fb_sink_; public: - void setAudioSink(MediaSink* audio_sink) { - boost::mutex::scoped_lock lock(monitor_mutex_); - this->audio_sink_ = audio_sink; + void setAudioSink(std::weak_ptr audio_sink) { + boost::mutex::scoped_lock lock(monitor_mutex_); + audio_sink_ = audio_sink; } - void setVideoSink(MediaSink* video_sink) { - boost::mutex::scoped_lock lock(monitor_mutex_); - this->video_sink_ = video_sink; + void setVideoSink(std::weak_ptr video_sink) { + boost::mutex::scoped_lock lock(monitor_mutex_); + video_sink_ = video_sink; } - void setEventSink(MediaSink* event_sink) { + void setEventSink(std::weak_ptr event_sink) { boost::mutex::scoped_lock lock(monitor_mutex_); - this->event_sink_ = event_sink; + event_sink_ = event_sink; } - FeedbackSink* getFeedbackSink() { - boost::mutex::scoped_lock lock(monitor_mutex_); - return source_fb_sink_; + std::weak_ptr getFeedbackSink() { + boost::mutex::scoped_lock lock(monitor_mutex_); + return source_fb_sink_; } virtual int sendPLI() = 0; uint32_t getVideoSourceSSRC() { @@ -255,7 +255,7 @@ class MediaSource: public virtual Monitor { } MediaSource() : audio_source_ssrc_{0}, video_source_ssrc_list_{std::vector(1, 0)}, - video_sink_{nullptr}, audio_sink_{nullptr}, event_sink_{nullptr}, source_fb_sink_{nullptr} {} + video_sink_{}, audio_sink_{}, event_sink_{}, source_fb_sink_{} {} virtual ~MediaSource() {} virtual boost::future close() = 0; diff --git a/erizo/src/erizo/MediaStream.cpp b/erizo/src/erizo/MediaStream.cpp index b5ca475c70..0276593fd0 100644 --- a/erizo/src/erizo/MediaStream.cpp +++ b/erizo/src/erizo/MediaStream.cpp @@ -82,8 +82,6 @@ MediaStream::MediaStream(std::shared_ptr worker, } ELOG_INFO("%s message: constructor, id: %s", toLog(), media_stream_id.c_str()); - source_fb_sink_ = this; - sink_fb_source_ = this; stats_ = std::make_shared(); log_stats_ = std::make_shared(); quality_manager_ = std::make_shared(); @@ -134,9 +132,9 @@ void MediaStream::syncClose() { } sending_ = false; ready_ = false; - video_sink_ = nullptr; - audio_sink_ = nullptr; - fb_sink_ = nullptr; + video_sink_.reset(); + audio_sink_.reset(); + fb_sink_.reset(); pipeline_initialized_ = false; pipeline_->close(); pipeline_.reset(); @@ -152,7 +150,16 @@ boost::future MediaStream::close() { }); } -bool MediaStream::init(bool doNotWaitForRemoteSdp) { +void MediaStream::init() { + if (source_fb_sink_.expired()) { + source_fb_sink_ = std::dynamic_pointer_cast(shared_from_this()); + } + if (sink_fb_source_.expired()) { + sink_fb_source_ = std::dynamic_pointer_cast(shared_from_this()); + } +} + +bool MediaStream::configure(bool doNotWaitForRemoteSdp) { if (doNotWaitForRemoteSdp) { ready_ = true; } @@ -210,7 +217,6 @@ bool MediaStream::setRemoteSdp(std::shared_ptr sdp, int session_version pipeline_->notifyUpdate(); return true; } - bundle_ = remote_sdp_->isBundle; if (video_ssrc_list_it != remote_sdp_->video_ssrc_map.end()) { setVideoSourceSSRCList(video_ssrc_list_it->second); @@ -493,7 +499,7 @@ int MediaStream::deliverEvent_(MediaEventPtr event) { } void MediaStream::onTransportData(std::shared_ptr incoming_packet, Transport *transport) { - if ((audio_sink_ == nullptr && video_sink_ == nullptr && fb_sink_ == nullptr)) { + if (audio_sink_.expired() && video_sink_.expired() && fb_sink_.expired()) { return; } @@ -537,6 +543,8 @@ void MediaStream::read(std::shared_ptr packet) { RtpHeader *head = reinterpret_cast (buf); RtcpHeader *chead = reinterpret_cast (buf); uint32_t recvSSRC = 0; + auto video_sink = video_sink_.lock(); + auto audio_sink = audio_sink_.lock(); if (!chead->isRtcp()) { recvSSRC = head->getSSRC(); } else if (chead->packettype == RTCP_Sender_PT || chead->packettype == RTCP_SDES_PT) { // Sender Report @@ -544,46 +552,47 @@ void MediaStream::read(std::shared_ptr packet) { } // DELIVER FEEDBACK (RR, FEEDBACK PACKETS) if (chead->isFeedback()) { - if (fb_sink_ != nullptr && should_send_feedback_) { - fb_sink_->deliverFeedback(std::move(packet)); + auto fb_sink = fb_sink_.lock(); + if (should_send_feedback_ && fb_sink) { + fb_sink->deliverFeedback(std::move(packet)); } } else { // RTP or RTCP Sender Report if (bundle_) { // Check incoming SSRC // Deliver data - if (isVideoSourceSSRC(recvSSRC) && video_sink_) { + if (isVideoSourceSSRC(recvSSRC) && video_sink) { parseIncomingPayloadType(buf, len, VIDEO_PACKET); parseIncomingExtensionId(buf, len, VIDEO_PACKET); - video_sink_->deliverVideoData(std::move(packet)); - } else if (isAudioSourceSSRC(recvSSRC) && audio_sink_) { + video_sink->deliverVideoData(std::move(packet)); + } else if (isAudioSourceSSRC(recvSSRC) && audio_sink) { parseIncomingPayloadType(buf, len, AUDIO_PACKET); parseIncomingExtensionId(buf, len, AUDIO_PACKET); - audio_sink_->deliverAudioData(std::move(packet)); + audio_sink->deliverAudioData(std::move(packet)); } else { ELOG_DEBUG("%s read video unknownSSRC: %u, localVideoSSRC: %u, localAudioSSRC: %u", toLog(), recvSSRC, this->getVideoSourceSSRC(), this->getAudioSourceSSRC()); } } else { - if (packet->type == AUDIO_PACKET && audio_sink_) { + if (packet->type == AUDIO_PACKET && audio_sink) { parseIncomingPayloadType(buf, len, AUDIO_PACKET); parseIncomingExtensionId(buf, len, AUDIO_PACKET); // Firefox does not send SSRC in SDP if (getAudioSourceSSRC() == 0) { ELOG_DEBUG("%s discoveredAudioSourceSSRC:%u", toLog(), recvSSRC); - this->setAudioSourceSSRC(recvSSRC); + setAudioSourceSSRC(recvSSRC); } - audio_sink_->deliverAudioData(std::move(packet)); - } else if (packet->type == VIDEO_PACKET && video_sink_) { + audio_sink->deliverAudioData(std::move(packet)); + } else if (packet->type == VIDEO_PACKET && video_sink) { parseIncomingPayloadType(buf, len, VIDEO_PACKET); parseIncomingExtensionId(buf, len, VIDEO_PACKET); // Firefox does not send SSRC in SDP if (getVideoSourceSSRC() == 0) { ELOG_DEBUG("%s discoveredVideoSourceSSRC:%u", toLog(), recvSSRC); - this->setVideoSourceSSRC(recvSSRC); + setVideoSourceSSRC(recvSSRC); } // change ssrc for RTP packets, don't touch here if RTCP - video_sink_->deliverVideoData(std::move(packet)); + video_sink->deliverVideoData(std::move(packet)); } } // if not bundle } // if not Feedback @@ -602,7 +611,9 @@ void MediaStream::notifyMediaStreamEvent(const std::string& type, const std::str } void MediaStream::notifyToEventSink(MediaEventPtr event) { - event_sink_->deliverEvent(std::move(event)); + if (auto event_sink = event_sink_.lock()) { + event_sink->deliverEvent(std::move(event)); + } } int MediaStream::sendPLI() { @@ -619,9 +630,8 @@ int MediaStream::sendPLI() { } void MediaStream::sendPLIToFeedback() { - if (fb_sink_) { - fb_sink_->deliverFeedback(RtpUtils::createPLI(this->getVideoSinkSSRC(), - this->getVideoSourceSSRC())); + if (auto fb_sink = fb_sink_.lock()) { + fb_sink->deliverFeedback(RtpUtils::createPLI(getVideoSinkSSRC(), getVideoSourceSSRC())); } } diff --git a/erizo/src/erizo/MediaStream.h b/erizo/src/erizo/MediaStream.h index 916fb3e06c..91a24a77e4 100644 --- a/erizo/src/erizo/MediaStream.h +++ b/erizo/src/erizo/MediaStream.h @@ -69,7 +69,8 @@ class MediaStream: public MediaSink, public MediaSource, public FeedbackSink, * Destructor. */ virtual ~MediaStream(); - bool init(bool doNotWaitForRemoteSdp); + void init(); + bool configure(bool doNotWaitForRemoteSdp); boost::future close() override; virtual uint32_t getMaxVideoBW(); virtual uint32_t getBitrateFromMaxQualityLayer() { return bitrate_from_max_quality_layer_; } diff --git a/erizo/src/erizo/OneToManyProcessor.cpp b/erizo/src/erizo/OneToManyProcessor.cpp index a34cbc85fc..72ec704ea8 100644 --- a/erizo/src/erizo/OneToManyProcessor.cpp +++ b/erizo/src/erizo/OneToManyProcessor.cpp @@ -13,7 +13,7 @@ namespace erizo { DEFINE_LOGGER(OneToManyProcessor, "OneToManyProcessor"); - OneToManyProcessor::OneToManyProcessor() : feedback_sink_{nullptr} { + OneToManyProcessor::OneToManyProcessor() : feedback_sink_{} { ELOG_DEBUG("OneToManyProcessor constructor"); } @@ -108,7 +108,7 @@ namespace erizo { } int OneToManyProcessor::deliverFeedback_(std::shared_ptr fb_packet) { - if (feedback_sink_ != nullptr) { + if (auto feedback_sink = feedback_sink_.lock()) { RtpUtils::forEachRtcpBlock(fb_packet, [this](RtcpHeader *chead) { if (chead->isREMB()) { for (uint8_t index = 0; index < chead->getREMBNumSSRC(); index++) { @@ -125,7 +125,7 @@ namespace erizo { chead->setSourceSSRC(publisher_->getVideoSourceSSRC()); } }); - feedback_sink_->deliverFeedback(fb_packet); + feedback_sink->deliverFeedback(fb_packet); } return 0; } @@ -152,11 +152,12 @@ namespace erizo { ELOG_DEBUG("Subscribers ssrcs: Audio %u, video, %u from %u, %u ", subscriber_stream->getAudioSinkSSRC(), subscriber_stream->getVideoSinkSSRC(), publisher_->getAudioSourceSSRC() , publisher_->getVideoSourceSSRC()); - FeedbackSource* fbsource = subscriber_stream->getFeedbackSource(); + std::shared_ptr fbsource = subscriber_stream->getFeedbackSource().lock(); - if (fbsource != nullptr) { + if (fbsource) { ELOG_DEBUG("adding fbsource"); - fbsource->setFeedbackSink(this); + auto fbsink = std::dynamic_pointer_cast(shared_from_this()); + fbsource->setFeedbackSink(fbsink); } if (subscribers_.find(peer_id) != subscribers_.end()) { ELOG_WARN("This OTM already has a subscriber with peer_id %s, substituting it", peer_id.c_str()); @@ -189,15 +190,15 @@ namespace erizo { ELOG_DEBUG("OneToManyProcessor closeAll"); std::shared_ptr> p = std::make_shared>(); boost::future f = p->get_future(); - feedback_sink_ = nullptr; + feedback_sink_.reset(); publisher_.reset(); boost::unique_lock lock(monitor_mutex_); std::map>::iterator it = subscribers_.begin(); while (it != subscribers_.end()) { if ((*it).second != nullptr) { - FeedbackSource* fbsource = (*it).second->getFeedbackSource(); - if (fbsource != nullptr) { - fbsource->setFeedbackSink(nullptr); + std::shared_ptr fbsource = (*it).second->getFeedbackSource().lock(); + if (fbsource) { + fbsource->setFeedbackSink(std::shared_ptr()); } } subscribers_.erase(it++); diff --git a/erizo/src/erizo/OneToManyProcessor.h b/erizo/src/erizo/OneToManyProcessor.h index f8f87e0f88..fc35ab7157 100644 --- a/erizo/src/erizo/OneToManyProcessor.h +++ b/erizo/src/erizo/OneToManyProcessor.h @@ -21,7 +21,8 @@ class MediaStream; * Represents a One to Many connection. * Receives media from one publisher and retransmits it to every subscriber. */ -class OneToManyProcessor : public MediaSink, public FeedbackSink { +class OneToManyProcessor + : public MediaSink, public FeedbackSink, public std::enable_shared_from_this { DECLARE_LOGGER(); public: @@ -61,7 +62,7 @@ class OneToManyProcessor : public MediaSink, public FeedbackSink { uint32_t translateAndMaybeAdaptForSimulcast(uint32_t orig_ssrc); private: - FeedbackSink* feedback_sink_; + std::weak_ptr feedback_sink_; std::map> subscribers_; std::shared_ptr publisher_; std::string publisher_id_; diff --git a/erizo/src/erizo/media/ExternalInput.cpp b/erizo/src/erizo/media/ExternalInput.cpp index 7d25a79f1d..673377eda8 100644 --- a/erizo/src/erizo/media/ExternalInput.cpp +++ b/erizo/src/erizo/media/ExternalInput.cpp @@ -209,7 +209,7 @@ int ExternalInput::deliverFeedback_(std::shared_ptr fb_packet) { } void ExternalInput::receiveRtpData(unsigned char* rtpdata, int len) { - if (video_sink_ != nullptr) { + if (auto video_sink = video_sink_.lock()) { RtcpHeader* head = reinterpret_cast(rtpdata); if (!head->isRtcp()) { if (getVideoSourceSSRC() == 0) { @@ -228,7 +228,7 @@ void ExternalInput::receiveRtpData(unsigned char* rtpdata, int len) { } else { packet->is_keyframe = false; } - video_sink_->deliverVideoData(packet); + video_sink->deliverVideoData(packet); } } @@ -276,7 +276,9 @@ void ExternalInput::receiveLoop() { if (length > 0) { std::shared_ptr packet = std::make_shared(0, reinterpret_cast(decodedBuffer_.get()), length, AUDIO_PACKET); - audio_sink_->deliverAudioData(packet); + if (auto audio_sink = audio_sink_.lock()) { + audio_sink->deliverAudioData(packet); + } } } } diff --git a/erizo/src/erizo/media/ExternalOutput.cpp b/erizo/src/erizo/media/ExternalOutput.cpp index 03947f55ff..cd0082e0aa 100644 --- a/erizo/src/erizo/media/ExternalOutput.cpp +++ b/erizo/src/erizo/media/ExternalOutput.cpp @@ -31,9 +31,6 @@ ExternalOutput::ExternalOutput(std::shared_ptr worker, const std::string audio_codec_{AV_CODEC_ID_NONE}, pipeline_initialized_{false}, ext_processor_{ext_mappings} { ELOG_DEBUG("Creating output to %s", output_url.c_str()); - fb_sink_ = nullptr; - sink_fb_source_ = this; - // TODO(pedro): these should really only be called once per application run av_register_all(); avcodec_register_all(); @@ -77,6 +74,7 @@ ExternalOutput::ExternalOutput(std::shared_ptr worker, const std::string } bool ExternalOutput::init() { + sink_fb_source_ = std::dynamic_pointer_cast(shared_from_this()); MediaInfo m; m.hasVideo = false; m.hasAudio = false; @@ -506,7 +504,7 @@ void ExternalOutput::queueData(char* buffer, int length, packetType type) { } int ExternalOutput::sendFirPacket() { - if (fb_sink_ != nullptr) { + if (auto fb_sink = fb_sink_.lock()) { RtcpHeader pli_header; pli_header.setPacketType(RTCP_PS_Feedback_PT); pli_header.setBlockCount(1); @@ -516,7 +514,7 @@ int ExternalOutput::sendFirPacket() { char *buf = reinterpret_cast(&pli_header); int len = (pli_header.getLength() + 1) * 4; std::shared_ptr pli_packet = std::make_shared(0, buf, len, VIDEO_PACKET); - fb_sink_->deliverFeedback(pli_packet); + fb_sink->deliverFeedback(pli_packet); return len; } return -1; diff --git a/erizo/src/erizo/media/SyntheticInput.cpp b/erizo/src/erizo/media/SyntheticInput.cpp index 1f949dcaa8..39544de097 100644 --- a/erizo/src/erizo/media/SyntheticInput.cpp +++ b/erizo/src/erizo/media/SyntheticInput.cpp @@ -135,8 +135,8 @@ void SyntheticInput::sendVideoframe(bool is_keyframe, bool is_marker, uint32_t s last_video_keyframe_time_ = clock_->now(); keyframe_requested_ = false; } - if (video_sink_) { - video_sink_->deliverVideoData(std::make_shared(0, packet_buffer, size, VIDEO_PACKET)); + if (auto video_sink = video_sink_.lock()) { + video_sink->deliverVideoData(std::make_shared(0, packet_buffer, size, VIDEO_PACKET)); } delete header; } @@ -151,8 +151,8 @@ void SyntheticInput::sendAudioFrame(uint32_t size) { char packet_buffer[kMaxPacketSize]; memset(packet_buffer, 0, size); memcpy(packet_buffer, reinterpret_cast(header), header->getHeaderLength()); - if (audio_sink_) { - audio_sink_->deliverAudioData(std::make_shared(0, packet_buffer, size, AUDIO_PACKET)); + if (auto audio_sink = audio_sink_.lock()) { + audio_sink->deliverAudioData(std::make_shared(0, packet_buffer, size, AUDIO_PACKET)); } delete header; } diff --git a/erizo/src/erizo/rtp/RtpSink.cpp b/erizo/src/erizo/rtp/RtpSink.cpp index 4fbf572750..68e7f2f0a9 100644 --- a/erizo/src/erizo/rtp/RtpSink.cpp +++ b/erizo/src/erizo/rtp/RtpSink.cpp @@ -88,8 +88,9 @@ namespace erizo { } void RtpSink::handleReceive(const::boost::system::error_code& error, size_t bytes_recvd) { // NOLINT - if (bytes_recvd > 0 && fb_sink_) { - fb_sink_->deliverFeedback(std::make_shared(0, reinterpret_cast(buffer_), + auto fb_sink = fb_sink_.lock(); + if (bytes_recvd > 0 && fb_sink) { + fb_sink->deliverFeedback(std::make_shared(0, reinterpret_cast(buffer_), static_cast(bytes_recvd), OTHER_PACKET)); } } diff --git a/erizo/src/erizo/rtp/RtpSource.cpp b/erizo/src/erizo/rtp/RtpSource.cpp index fbac7999d9..0d84101b8b 100644 --- a/erizo/src/erizo/rtp/RtpSource.cpp +++ b/erizo/src/erizo/rtp/RtpSource.cpp @@ -39,8 +39,9 @@ int RtpSource::deliverFeedback_(std::shared_ptr fb_packet) { } void RtpSource::handleReceive(const::boost::system::error_code& error, size_t bytes_recvd) { // NOLINT - if (bytes_recvd > 0 && this->video_sink_) { - this->video_sink_->deliverVideoData(std::make_shared(0, reinterpret_cast(buffer_), + auto video_sink = video_sink_.lock(); + if (bytes_recvd > 0 && video_sink) { + video_sink->deliverVideoData(std::make_shared(0, reinterpret_cast(buffer_), static_cast(bytes_recvd), OTHER_PACKET)); } } diff --git a/erizo/src/test/OneToManyProcessorTest.cpp b/erizo/src/test/OneToManyProcessorTest.cpp index 3bf0d132d2..6c88da6050 100644 --- a/erizo/src/test/OneToManyProcessorTest.cpp +++ b/erizo/src/test/OneToManyProcessorTest.cpp @@ -14,12 +14,12 @@ using erizo::MediaEventPtr; static const char kArbitraryPeerId[] = "111"; -class MockPublisher: public erizo::MediaSource, public erizo::FeedbackSink { +class MockPublisher + : public erizo::MediaSource, public erizo::FeedbackSink, public std::enable_shared_from_this { public: MockPublisher() { video_source_ssrc_list_[0] = 1; audio_source_ssrc_ = 2; - source_fb_sink_ = this; } ~MockPublisher() {} boost::future close() override { @@ -27,6 +27,12 @@ class MockPublisher: public erizo::MediaSource, public erizo::FeedbackSink { p->set_value(); return p->get_future(); } + + void setAsSelfFeedbackSink() { + auto fb_sink = std::dynamic_pointer_cast(shared_from_this()); + source_fb_sink_ = fb_sink; + } + int sendPLI() override { return 0; } int deliverFeedback_(std::shared_ptr packet) override { return internalDeliverFeedback_(packet); @@ -37,7 +43,6 @@ class MockPublisher: public erizo::MediaSource, public erizo::FeedbackSink { class MockSubscriber: public erizo::MediaSink, public erizo::FeedbackSource { public: MockSubscriber() { - sink_fb_source_ = this; } ~MockSubscriber() {} boost::future close() override { @@ -64,6 +69,7 @@ class OneToManyProcessorTest : public ::testing::Test { protected: virtual void SetUp() { publisher = std::make_shared(); + publisher->setAsSelfFeedbackSink(); subscriber = std::make_shared(); otm.setPublisher(publisher, "1"); otm.addSubscriber(subscriber, kArbitraryPeerId); diff --git a/erizo/src/test/media/SyntheticInputTest.cpp b/erizo/src/test/media/SyntheticInputTest.cpp index 38a4b3c235..51d10d01bd 100644 --- a/erizo/src/test/media/SyntheticInputTest.cpp +++ b/erizo/src/test/media/SyntheticInputTest.cpp @@ -29,7 +29,8 @@ using erizo::Worker; class SyntheticInputTest : public ::testing::Test { public: SyntheticInputTest() - : config{30000, 0, 5000000}, + : sink{std::make_shared()}, + config{30000, 0, 5000000}, clock{std::make_shared()}, worker{std::make_shared(clock)}, input{std::make_shared(config, worker, clock)} @@ -40,8 +41,8 @@ class SyntheticInputTest : public ::testing::Test { protected: virtual void SetUp() { - input->setVideoSink(&sink); - input->setAudioSink(&sink); + input->setVideoSink(sink); + input->setAudioSink(sink); input->start(); } @@ -56,7 +57,7 @@ class SyntheticInputTest : public ::testing::Test { } } - erizo::MockMediaSink sink; + std::shared_ptr sink; SyntheticInputConfig config; std::shared_ptr clock; std::shared_ptr worker; @@ -68,69 +69,69 @@ ACTION_P(SaveTimestamp, target) { } TEST_F(SyntheticInputTest, shouldWriteAudioPackets_whenExpected) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(0))).Times(1); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).Times(0); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(0))).Times(1); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).Times(0); executeTasksInNextMs(20); } TEST_F(SyntheticInputTest, shouldWriteVideoPackets_whenExpected) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(4); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(4); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).Times(1); executeTasksInNextMs(80); } TEST_F(SyntheticInputTest, shouldWriteMultiplePackets_after1Secong) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(50); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).Times(15); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(50); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).Times(15); executeTasksInNextMs(1000); } TEST_F(SyntheticInputTest, shouldWriteAudioFrames_WithExpectedPT) { size_t opusPayloadType = 111; - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasPayloadType(opusPayloadType))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasPayloadType(opusPayloadType))).Times(1); executeTasksInNextMs(20); } TEST_F(SyntheticInputTest, shouldWriteVideoFrames_WithExpectedPT) { size_t vp8PayloadType = 100; - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(4); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasPayloadType(vp8PayloadType))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(4); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasPayloadType(vp8PayloadType))).Times(1); executeTasksInNextMs(80); } TEST_F(SyntheticInputTest, shouldWriteAudioFrames_WithExpectedSsrc) { size_t audioSsrc = 44444; - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSsrc(audioSsrc))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSsrc(audioSsrc))).Times(1); executeTasksInNextMs(20); } TEST_F(SyntheticInputTest, shouldWriteVideoFrames_WithExpectedSsrc) { size_t videoSsrc = 55543; - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(4); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasSsrc(videoSsrc))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(4); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasSsrc(videoSsrc))).Times(1); executeTasksInNextMs(80); } TEST_F(SyntheticInputTest, shouldWriteAudioFrames_WithIncreasingSequenceNumbers) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(0))).Times(1); - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(1))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(0))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(1))).Times(1); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).Times(0); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).Times(0); executeTasksInNextMs(40); } TEST_F(SyntheticInputTest, shouldWriteVideoFrames_WithIncreasingSequenceNumbers) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(7); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(7); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(0))).Times(1); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(1))).Times(1); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(0))).Times(1); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::RtpHasSequenceNumberFromBuffer(1))).Times(1); executeTasksInNextMs(140); } @@ -141,8 +142,8 @@ TEST_F(SyntheticInputTest, shouldWriteAudioFrames_WithIncreasingTimestamps) { { InSequence s; - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&first_timestamp)); - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&second_timestamp)); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&first_timestamp)); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&second_timestamp)); } executeTasksInNextMs(40); @@ -156,11 +157,11 @@ TEST_F(SyntheticInputTest, shouldWriteVideoFrames_WithIncreasingTimestamps) { { InSequence s; - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&first_timestamp)); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&second_timestamp)); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&first_timestamp)); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).Times(1).WillOnce(SaveTimestamp(&second_timestamp)); } - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(7); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(7); executeTasksInNextMs(140); @@ -168,9 +169,9 @@ TEST_F(SyntheticInputTest, shouldWriteVideoFrames_WithIncreasingTimestamps) { } TEST_F(SyntheticInputTest, firstVideoFrame_shouldBeAKeyframe) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(7); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(1); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(Not(erizo::IsKeyframeFirstPacket()))).Times(1); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(7); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(1); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(Not(erizo::IsKeyframeFirstPacket()))).Times(1); executeTasksInNextMs(140); } @@ -178,17 +179,17 @@ TEST_F(SyntheticInputTest, firstVideoFrame_shouldBeAKeyframe) { TEST_F(SyntheticInputTest, shouldWriteFragmentedKeyFrames_whenExpected) { auto packet = erizo::PacketTools::createRembPacket(350000); input->deliverFeedback(packet); - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(4); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(1); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(Not(erizo::IsKeyframeFirstPacket()))).Times(2); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(4); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(1); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(Not(erizo::IsKeyframeFirstPacket()))).Times(2); executeTasksInNextMs(80); } TEST_F(SyntheticInputTest, shouldWriteKeyFrames_whenPliIsReceived) { auto packet = erizo::PacketTools::createPLI(); - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(7); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(2); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(7); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(2); executeTasksInNextMs(80); @@ -198,8 +199,8 @@ TEST_F(SyntheticInputTest, shouldWriteKeyFrames_whenPliIsReceived) { } TEST_F(SyntheticInputTest, shouldWriteKeyFrames_whenRequestedByControl) { - EXPECT_CALL(sink, deliverAudioDataInternal(_, _)).Times(7); - EXPECT_CALL(sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(2); + EXPECT_CALL(*sink, deliverAudioDataInternal(_, _)).Times(7); + EXPECT_CALL(*sink, deliverVideoDataInternal(_, _)).With(Args<0>(erizo::IsKeyframeFirstPacket())).Times(2); executeTasksInNextMs(80); diff --git a/erizoAPI/ExternalInput.cc b/erizoAPI/ExternalInput.cc index 70376b3dd2..f5aedda124 100644 --- a/erizoAPI/ExternalInput.cc +++ b/erizoAPI/ExternalInput.cc @@ -97,10 +97,9 @@ NAN_METHOD(ExternalInput::setAudioReceiver) { std::shared_ptr me = obj->me; MediaSink* param = ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::MediaSink *mr = param->msink; - me->setAudioSink(mr); - me->setEventSink(mr); + me->setAudioSink(param->msink); + me->setEventSink(param->msink); } NAN_METHOD(ExternalInput::setVideoReceiver) { @@ -108,10 +107,9 @@ NAN_METHOD(ExternalInput::setVideoReceiver) { std::shared_ptr me = obj->me; MediaSink* param = ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::MediaSink *mr = param->msink; - me->setVideoSink(mr); - me->setEventSink(mr); + me->setVideoSink(param->msink); + me->setEventSink(param->msink); } NAN_METHOD(ExternalInput::generatePLIPacket) { diff --git a/erizoAPI/MediaDefinitions.h b/erizoAPI/MediaDefinitions.h index 1b49e2d4ce..fb88415016 100644 --- a/erizoAPI/MediaDefinitions.h +++ b/erizoAPI/MediaDefinitions.h @@ -10,7 +10,7 @@ */ class MediaSink : public Nan::ObjectWrap { public: - erizo::MediaSink* msink; + std::weak_ptr msink; }; @@ -19,7 +19,7 @@ class MediaSink : public Nan::ObjectWrap { */ class MediaSource : public Nan::ObjectWrap { public: - erizo::MediaSource* msource; + std::weak_ptr msource; }; #endif // ERIZOAPI_MEDIADEFINITIONS_H_ diff --git a/erizoAPI/MediaStream.cc b/erizoAPI/MediaStream.cc index 8fce0f6b20..f3ff2bafd4 100644 --- a/erizoAPI/MediaStream.cc +++ b/erizoAPI/MediaStream.cc @@ -125,7 +125,7 @@ NAN_MODULE_INIT(MediaStream::Init) { // Prototype Nan::SetPrototypeMethod(tpl, "close", close); - Nan::SetPrototypeMethod(tpl, "init", init); + Nan::SetPrototypeMethod(tpl, "configure", configure); Nan::SetPrototypeMethod(tpl, "setAudioReceiver", setAudioReceiver); Nan::SetPrototypeMethod(tpl, "setVideoReceiver", setVideoReceiver); Nan::SetPrototypeMethod(tpl, "getCurrentState", getCurrentState); @@ -177,7 +177,8 @@ NAN_METHOD(MediaStream::New) { MediaStream* obj = new MediaStream(); obj->me = std::make_shared(worker, wrtc, wrtc_id, stream_label, is_publisher, session_version); - obj->msink = obj->me.get(); + obj->me->init(); + obj->msink = obj->me; obj->id_ = wrtc_id; obj->label_ = stream_label; ELOG_DEBUG("%s, message: Created", obj->toLog()); @@ -201,14 +202,14 @@ NAN_METHOD(MediaStream::close) { info.GetReturnValue().Set(resolver->GetPromise()); } -NAN_METHOD(MediaStream::init) { +NAN_METHOD(MediaStream::configure) { MediaStream* obj = Nan::ObjectWrap::Unwrap(info.Holder()); std::shared_ptr me = obj->me; if (!me || obj->closed_) { return; } bool force = info.Length() > 0 ? Nan::To(info[0]).FromJust() : false; - bool r = me->init(force); + bool r = me->configure(force); info.GetReturnValue().Set(Nan::New(r)); } @@ -309,10 +310,9 @@ NAN_METHOD(MediaStream::setAudioReceiver) { } MediaSink* param = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::MediaSink *mr = param->msink; - me->setAudioSink(mr); - me->setEventSink(mr); + me->setAudioSink(param->msink); + me->setEventSink(param->msink); } NAN_METHOD(MediaStream::setVideoReceiver) { @@ -323,10 +323,9 @@ NAN_METHOD(MediaStream::setVideoReceiver) { } MediaSink* param = Nan::ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::MediaSink *mr = param->msink; - me->setVideoSink(mr); - me->setEventSink(mr); + me->setVideoSink(param->msink); + me->setEventSink(param->msink); } diff --git a/erizoAPI/MediaStream.h b/erizoAPI/MediaStream.h index 57ebd76a6f..b35c30b032 100644 --- a/erizoAPI/MediaStream.h +++ b/erizoAPI/MediaStream.h @@ -76,10 +76,9 @@ class MediaStream : public MediaSink, public erizo::MediaStreamStatsListener, pu */ static NAN_METHOD(close); /* - * Inits the MediaStream and passes the callback to get Events. - * Returns true if the candidates are gathered. + * Configures the MediaStream. */ - static NAN_METHOD(init); + static NAN_METHOD(configure); /* * Sets a MediaReceiver that is going to receive Audio Data * Param: the MediaReceiver to send audio to. diff --git a/erizoAPI/OneToManyProcessor.cc b/erizoAPI/OneToManyProcessor.cc index 143f5d1a62..7aab6cc118 100644 --- a/erizoAPI/OneToManyProcessor.cc +++ b/erizoAPI/OneToManyProcessor.cc @@ -87,7 +87,7 @@ NAN_MODULE_INIT(OneToManyProcessor::Init) { NAN_METHOD(OneToManyProcessor::New) { OneToManyProcessor* obj = new OneToManyProcessor(); obj->me = std::make_shared(); - obj->msink = obj->me.get(); + obj->msink = obj->me; obj->Wrap(info.This()); info.GetReturnValue().Set(info.This()); diff --git a/erizoAPI/SyntheticInput.cc b/erizoAPI/SyntheticInput.cc index 75f9940138..3157f5fab4 100644 --- a/erizoAPI/SyntheticInput.cc +++ b/erizoAPI/SyntheticInput.cc @@ -106,10 +106,9 @@ NAN_METHOD(SyntheticInput::setAudioReceiver) { std::shared_ptr me = obj->me; MediaSink* param = ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::MediaSink *mr = param->msink; - me->setAudioSink(mr); - me->setEventSink(mr); + me->setAudioSink(param->msink); + me->setEventSink(param->msink); } NAN_METHOD(SyntheticInput::setVideoReceiver) { @@ -117,10 +116,9 @@ NAN_METHOD(SyntheticInput::setVideoReceiver) { std::shared_ptr me = obj->me; MediaSink* param = ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::MediaSink *mr = param->msink; - me->setVideoSink(mr); - me->setEventSink(mr); + me->setVideoSink(param->msink); + me->setEventSink(param->msink); } NAN_METHOD(SyntheticInput::setFeedbackSource) { @@ -128,9 +126,9 @@ NAN_METHOD(SyntheticInput::setFeedbackSource) { std::shared_ptr me = obj->me; MediaStream* param = ObjectWrap::Unwrap(Nan::To(info[0]).ToLocalChecked()); - erizo::FeedbackSource* fb_source = param->me->getFeedbackSource(); + std::shared_ptr fb_source = param->me->getFeedbackSource().lock(); - if (fb_source != nullptr) { - fb_source->setFeedbackSink(me.get()); + if (fb_source) { + fb_source->setFeedbackSink(me); } } diff --git a/erizo_controller/erizoJS/models/Node.js b/erizo_controller/erizoJS/models/Node.js index e8ebbc561e..6d96df0801 100644 --- a/erizo_controller/erizoJS/models/Node.js +++ b/erizo_controller/erizoJS/models/Node.js @@ -54,7 +54,7 @@ class Node extends EventEmitter { return; } const mediaStream = this.mediaStream; - mediaStream.init(force); + mediaStream.configure(force); if (mediaStream.minVideoBW) { let monitorMinVideoBw = {}; if (mediaStream.scheme) { diff --git a/erizo_controller/test/utils.js b/erizo_controller/test/utils.js index c7d60eae4e..3e93e0015e 100644 --- a/erizo_controller/test/utils.js +++ b/erizo_controller/test/utils.js @@ -174,7 +174,7 @@ module.exports.reset = () => { scheme: '', periodicPlis: '', close: sinon.stub(), - init: sinon.stub(), + configure: sinon.stub(), setAudioReceiver: sinon.stub(), setVideoReceiver: sinon.stub(), setMaxVideoBW: sinon.stub(),