Add IsEmpty to RtpStreamReceiverController and RtpDemuxer Additionally make ResolveSink public and expose it via the RtpStreamReceiverController class. This allows decoupling the demuxing operations from the receiving sinks in a follow-up set of changes as operations are moved from the worker thread to the network thread. Bug: webrtc:42222117 Change-Id: I68716390cf655e7134b75667e39f678285c83760 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/471120 Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47680}
diff --git a/call/call.cc b/call/call.cc index 2cae632..6110758 100644 --- a/call/call.cc +++ b/call/call.cc
@@ -749,6 +749,8 @@ RTC_CHECK(video_send_streams_.empty()); RTC_CHECK(audio_receive_streams_.empty()); RTC_CHECK(video_receive_streams_.empty()); + RTC_CHECK(audio_receiver_controller_.IsEmpty()); + RTC_CHECK(video_receiver_controller_.IsEmpty()); receive_side_cc_periodic_task_.Stop(); elastic_bandwidth_allocation_task_.Stop();
diff --git a/call/rtp_demuxer.cc b/call/rtp_demuxer.cc index e078347..6821fe0 100644 --- a/call/rtp_demuxer.cc +++ b/call/rtp_demuxer.cc
@@ -125,6 +125,12 @@ RTC_DCHECK(sink_by_rsid_.empty()); } +bool RtpDemuxer::IsEmpty() const { + return sink_by_mid_.empty() && sink_by_ssrc_.empty() && + sinks_by_pt_.empty() && sink_by_mid_and_rsid_.empty() && + sink_by_rsid_.empty() && match_any_sink_ == nullptr; +} + bool RtpDemuxer::AddSink(const RtpDemuxerCriteria& criteria, RtpPacketSinkInterface* sink) { RTC_DCHECK(criteria.match_any() || !criteria.payload_types().empty() || @@ -193,9 +199,7 @@ if (criteria.match_any()) { // A match_all criteria conflicts if and only if we have another sink // already registered. - return (!sink_by_mid_.empty() || !sink_by_ssrc_.empty() || - !sinks_by_pt_.empty() || !sink_by_mid_and_rsid_.empty() || - !sink_by_rsid_.empty()); + return !IsEmpty(); } if (!criteria.mid().empty()) {
diff --git a/call/rtp_demuxer.h b/call/rtp_demuxer.h index f2f76cb..24d50de 100644 --- a/call/rtp_demuxer.h +++ b/call/rtp_demuxer.h
@@ -140,6 +140,8 @@ use_payload_type_demuxing_ = enable; } + bool IsEmpty() const; + // Registers a sink that will be notified when RTP packets match its given // criteria according to the algorithm described in the class description. // Returns true if the sink was successfully added. @@ -171,6 +173,12 @@ // Returns the set of SSRCs associated with a sink. flat_set<uint32_t> GetSsrcsForSink(const RtpPacketSinkInterface* sink) const; + // Runs the demux algorithm on the given packet and returns the sink that + // should receive the packet. + // Will record any SSRC<->ID associations along the way. + // If the packet should be dropped, this method returns null. + RtpPacketSinkInterface* ResolveSink(const RtpPacketReceived& packet); + // Demuxes the given packet and forwards it to the chosen sink. Returns true // if the packet was forwarded and false if the packet was dropped. bool OnRtpPacket(const RtpPacketReceived& packet); @@ -180,12 +188,6 @@ // with the existing criteria and should be rejected. bool CriteriaWouldConflict(const RtpDemuxerCriteria& criteria) const; - // Runs the demux algorithm on the given packet and returns the sink that - // should receive the packet. - // Will record any SSRC<->ID associations along the way. - // If the packet should be dropped, this method returns null. - RtpPacketSinkInterface* ResolveSink(const RtpPacketReceived& packet); - // Used by the ResolveSink algorithm. RtpPacketSinkInterface* ResolveSinkByMid(absl::string_view mid, uint32_t ssrc);
diff --git a/call/rtp_demuxer_unittest.cc b/call/rtp_demuxer_unittest.cc index b878d2b..c358b5e 100644 --- a/call/rtp_demuxer_unittest.cc +++ b/call/rtp_demuxer_unittest.cc
@@ -1349,6 +1349,30 @@ EXPECT_FALSE(demuxer_.OnRtpPacket(*packet)); } +TEST_F(RtpDemuxerTest, IsEmptyMatchesSinksPresence) { + EXPECT_TRUE(demuxer_.IsEmpty()); + + MockRtpPacketSink sink; + constexpr uint32_t ssrc = 101; + EXPECT_TRUE(AddSinkOnlySsrc(ssrc, &sink)); + EXPECT_FALSE(demuxer_.IsEmpty()); + + EXPECT_TRUE(RemoveSink(&sink)); + EXPECT_TRUE(demuxer_.IsEmpty()); +} + +TEST_F(RtpDemuxerTest, ResolveSinkReturnsCorrectSink) { + constexpr uint32_t ssrc = 101; + MockRtpPacketSink sink; + EXPECT_TRUE(AddSinkOnlySsrc(ssrc, &sink)); + + auto packet = CreatePacketWithSsrc(ssrc); + EXPECT_EQ(demuxer_.ResolveSink(*packet), &sink); + + auto unknown_packet = CreatePacketWithSsrc(ssrc + 1); + EXPECT_EQ(demuxer_.ResolveSink(*unknown_packet), nullptr); +} + #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) TEST_F(RtpDemuxerDeathTest, MidMustNotExceedMaximumLength) {
diff --git a/call/rtp_stream_receiver_controller.cc b/call/rtp_stream_receiver_controller.cc index 9367b87..68b979d 100644 --- a/call/rtp_stream_receiver_controller.cc +++ b/call/rtp_stream_receiver_controller.cc
@@ -49,6 +49,17 @@ return std::make_unique<Receiver>(this, ssrc, sink); } +bool RtpStreamReceiverController::IsEmpty() const { + RTC_DCHECK_RUN_ON(&demuxer_sequence_); + return demuxer_.IsEmpty(); +} + +RtpPacketSinkInterface* RtpStreamReceiverController::ResolveSink( + const RtpPacketReceived& packet) { + RTC_DCHECK_RUN_ON(&demuxer_sequence_); + return demuxer_.ResolveSink(packet); +} + bool RtpStreamReceiverController::OnRtpPacket(const RtpPacketReceived& packet) { RTC_DCHECK_RUN_ON(&demuxer_sequence_); return demuxer_.OnRtpPacket(packet);
diff --git a/call/rtp_stream_receiver_controller.h b/call/rtp_stream_receiver_controller.h index 1954c4f..a10d774 100644 --- a/call/rtp_stream_receiver_controller.h +++ b/call/rtp_stream_receiver_controller.h
@@ -38,6 +38,8 @@ uint32_t ssrc, RtpPacketSinkInterface* sink) override; + RtpPacketSinkInterface* ResolveSink(const RtpPacketReceived& packet); + // TODO(bugs.webrtc.org/7135): Not yet responsible for parsing. bool OnRtpPacket(const RtpPacketReceived& packet); @@ -45,6 +47,8 @@ // Responsible for demuxing recovered FLEXFEC packets. void OnRecoveredPacket(const RtpPacketReceived& packet) override; + bool IsEmpty() const; + private: class Receiver : public RtpStreamReceiverInterface { public: