mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 14:20:45 +01:00
Add MID sending to RTPSender
This CL adds the ability to configure RTPSender to include the MID header extension when sending packets. The MID will be included on every packet at the start of the stream until an RTCP acknoledgment is received for that SSRC at which point it will stop being included. The MID will be included on regular RTP streams as well as RTX streams. Bug: webrtc:4050 Change-Id: Ie27ebee1cd00a67f2b931f5363788f523e3e684f Reviewed-on: https://webrtc-review.googlesource.com/60582 Commit-Queue: Steve Anton <steveanton@webrtc.org> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22574}
This commit is contained in:
parent
ba2a9237da
commit
296a0ce4c7
12 changed files with 269 additions and 1 deletions
|
@ -121,6 +121,8 @@ rtc_static_library("rtp_rtcp") {
|
||||||
"source/forward_error_correction.h",
|
"source/forward_error_correction.h",
|
||||||
"source/forward_error_correction_internal.cc",
|
"source/forward_error_correction_internal.cc",
|
||||||
"source/forward_error_correction_internal.h",
|
"source/forward_error_correction_internal.h",
|
||||||
|
"source/mid_oracle.cc",
|
||||||
|
"source/mid_oracle.h",
|
||||||
"source/packet_loss_stats.cc",
|
"source/packet_loss_stats.cc",
|
||||||
"source/packet_loss_stats.h",
|
"source/packet_loss_stats.h",
|
||||||
"source/playout_delay_oracle.cc",
|
"source/playout_delay_oracle.cc",
|
||||||
|
@ -332,6 +334,7 @@ if (rtc_include_tests) {
|
||||||
"source/flexfec_header_reader_writer_unittest.cc",
|
"source/flexfec_header_reader_writer_unittest.cc",
|
||||||
"source/flexfec_receiver_unittest.cc",
|
"source/flexfec_receiver_unittest.cc",
|
||||||
"source/flexfec_sender_unittest.cc",
|
"source/flexfec_sender_unittest.cc",
|
||||||
|
"source/mid_oracle_unittest.cc",
|
||||||
"source/nack_rtx_unittest.cc",
|
"source/nack_rtx_unittest.cc",
|
||||||
"source/packet_loss_stats_unittest.cc",
|
"source/packet_loss_stats_unittest.cc",
|
||||||
"source/playout_delay_oracle_unittest.cc",
|
"source/playout_delay_oracle_unittest.cc",
|
||||||
|
|
|
@ -171,6 +171,11 @@ class RtpRtcp : public Module, public RtcpFeedbackSenderInterface {
|
||||||
// Sets SSRC, default is a random number.
|
// Sets SSRC, default is a random number.
|
||||||
virtual void SetSSRC(uint32_t ssrc) = 0;
|
virtual void SetSSRC(uint32_t ssrc) = 0;
|
||||||
|
|
||||||
|
// Sets the value for sending in the MID RTP header extension.
|
||||||
|
// The MID RTP header extension should be registered for this to do anything.
|
||||||
|
// Once set, this value can not be changed or removed.
|
||||||
|
virtual void SetMid(const std::string& mid) = 0;
|
||||||
|
|
||||||
// Sets CSRC.
|
// Sets CSRC.
|
||||||
// |csrcs| - vector of CSRCs
|
// |csrcs| - vector of CSRCs
|
||||||
virtual void SetCsrcs(const std::vector<uint32_t>& csrcs) = 0;
|
virtual void SetCsrcs(const std::vector<uint32_t>& csrcs) = 0;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#define MODULES_RTP_RTCP_MOCKS_MOCK_RTP_RTCP_H_
|
#define MODULES_RTP_RTCP_MOCKS_MOCK_RTP_RTCP_H_
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ class MockRtpRtcp : public RtpRtcp {
|
||||||
MOCK_CONST_METHOD0(GetRtxState, RtpState());
|
MOCK_CONST_METHOD0(GetRtxState, RtpState());
|
||||||
MOCK_CONST_METHOD0(SSRC, uint32_t());
|
MOCK_CONST_METHOD0(SSRC, uint32_t());
|
||||||
MOCK_METHOD1(SetSSRC, void(uint32_t ssrc));
|
MOCK_METHOD1(SetSSRC, void(uint32_t ssrc));
|
||||||
|
MOCK_METHOD1(SetMid, void(const std::string& mid));
|
||||||
MOCK_CONST_METHOD1(CSRCs, int32_t(uint32_t csrcs[kRtpCsrcSize]));
|
MOCK_CONST_METHOD1(CSRCs, int32_t(uint32_t csrcs[kRtpCsrcSize]));
|
||||||
MOCK_METHOD1(SetCsrcs, void(const std::vector<uint32_t>& csrcs));
|
MOCK_METHOD1(SetCsrcs, void(const std::vector<uint32_t>& csrcs));
|
||||||
MOCK_METHOD1(SetCSRCStatus, int32_t(bool include));
|
MOCK_METHOD1(SetCSRCStatus, int32_t(bool include));
|
||||||
|
|
32
modules/rtp_rtcp/source/mid_oracle.cc
Normal file
32
modules/rtp_rtcp/source/mid_oracle.cc
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modules/rtp_rtcp/source/mid_oracle.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
MidOracle::MidOracle(const std::string& mid) : mid_(mid) {}
|
||||||
|
|
||||||
|
MidOracle::~MidOracle() = default;
|
||||||
|
|
||||||
|
void MidOracle::OnReceivedRtcpReportBlocks(
|
||||||
|
const ReportBlockList& report_blocks) {
|
||||||
|
if (!send_mid_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const RTCPReportBlock& report_block : report_blocks) {
|
||||||
|
if (report_block.source_ssrc == ssrc_) {
|
||||||
|
send_mid_ = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
58
modules/rtp_rtcp/source/mid_oracle.h
Normal file
58
modules/rtp_rtcp/source/mid_oracle.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MODULES_RTP_RTCP_SOURCE_MID_ORACLE_H_
|
||||||
|
#define MODULES_RTP_RTCP_SOURCE_MID_ORACLE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
|
#include "rtc_base/constructormagic.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// The MidOracle instructs an RTPSender to send the MID header extension on a
|
||||||
|
// new SSRC stream until it receives an RTCP report block for that stream (which
|
||||||
|
// implies that the remote side is able to demultiplex it and can remember the
|
||||||
|
// MID --> SSRC mapping).
|
||||||
|
class MidOracle {
|
||||||
|
public:
|
||||||
|
explicit MidOracle(const std::string& mid);
|
||||||
|
~MidOracle();
|
||||||
|
|
||||||
|
// MID value to put into the header extension.
|
||||||
|
const std::string& mid() const { return mid_; }
|
||||||
|
|
||||||
|
// True if the MID header extension should be included on the next outgoing
|
||||||
|
// packet.
|
||||||
|
bool send_mid() const { return send_mid_; }
|
||||||
|
|
||||||
|
// Change the RTP stream SSRC. This will cause MIDs to be included until an
|
||||||
|
// RTCP report block lists this SSRC as received.
|
||||||
|
void SetSsrc(uint32_t ssrc) {
|
||||||
|
ssrc_ = ssrc;
|
||||||
|
send_mid_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feedback to decide when to stop sending the MID header extension.
|
||||||
|
void OnReceivedRtcpReportBlocks(const ReportBlockList& report_blocks);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string mid_;
|
||||||
|
bool send_mid_ = false;
|
||||||
|
uint32_t ssrc_ = 0;
|
||||||
|
|
||||||
|
RTC_DISALLOW_COPY_AND_ASSIGN(MidOracle);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // MODULES_RTP_RTCP_SOURCE_MID_ORACLE_H_
|
68
modules/rtp_rtcp/source/mid_oracle_unittest.cc
Normal file
68
modules/rtp_rtcp/source/mid_oracle_unittest.cc
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modules/rtp_rtcp/source/mid_oracle.h"
|
||||||
|
|
||||||
|
#include "rtc_base/logging.h"
|
||||||
|
#include "test/gtest.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::webrtc::RTCPReportBlock;
|
||||||
|
using ::webrtc::MidOracle;
|
||||||
|
|
||||||
|
RTCPReportBlock ReportBlockWithSourceSsrc(uint32_t ssrc) {
|
||||||
|
RTCPReportBlock report_block;
|
||||||
|
report_block.source_ssrc = ssrc;
|
||||||
|
return report_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidOracleTest, DoNotSendMidInitially) {
|
||||||
|
MidOracle mid_oracle("mid");
|
||||||
|
EXPECT_FALSE(mid_oracle.send_mid());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidOracleTest, SendMidOnceSsrcSet) {
|
||||||
|
MidOracle mid_oracle("mid");
|
||||||
|
mid_oracle.SetSsrc(52);
|
||||||
|
EXPECT_TRUE(mid_oracle.send_mid());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidOracleTest, IgnoreReportBlockWithUnknownSourceSsrc) {
|
||||||
|
MidOracle mid_oracle("mid");
|
||||||
|
mid_oracle.SetSsrc(52);
|
||||||
|
mid_oracle.OnReceivedRtcpReportBlocks({ReportBlockWithSourceSsrc(63)});
|
||||||
|
EXPECT_TRUE(mid_oracle.send_mid());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidOracleTest, StopSendingMidAfterReceivingRtcpReportWithKnownSourceSsrc) {
|
||||||
|
constexpr uint32_t kSsrc = 52;
|
||||||
|
|
||||||
|
MidOracle mid_oracle("mid");
|
||||||
|
mid_oracle.SetSsrc(kSsrc);
|
||||||
|
mid_oracle.OnReceivedRtcpReportBlocks({ReportBlockWithSourceSsrc(kSsrc)});
|
||||||
|
|
||||||
|
EXPECT_FALSE(mid_oracle.send_mid());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(MidOracleTest, RestartSendingMidWhenSsrcChanges) {
|
||||||
|
constexpr uint32_t kInitialSsrc = 52;
|
||||||
|
constexpr uint32_t kChangedSsrc = 63;
|
||||||
|
|
||||||
|
MidOracle mid_oracle("mid");
|
||||||
|
mid_oracle.SetSsrc(kInitialSsrc);
|
||||||
|
mid_oracle.OnReceivedRtcpReportBlocks(
|
||||||
|
{ReportBlockWithSourceSsrc(kInitialSsrc)});
|
||||||
|
mid_oracle.SetSsrc(kChangedSsrc);
|
||||||
|
|
||||||
|
EXPECT_TRUE(mid_oracle.send_mid());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
|
@ -340,6 +340,14 @@ void ModuleRtpRtcpImpl::SetSSRC(const uint32_t ssrc) {
|
||||||
SetRtcpReceiverSsrcs(ssrc);
|
SetRtcpReceiverSsrcs(ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleRtpRtcpImpl::SetMid(const std::string& mid) {
|
||||||
|
if (rtp_sender_) {
|
||||||
|
rtp_sender_->SetMid(mid);
|
||||||
|
}
|
||||||
|
// TODO(bugs.webrtc.org/4050): If we end up supporting the MID SDES item for
|
||||||
|
// RTCP, this will need to be passed down to the RTCPSender also.
|
||||||
|
}
|
||||||
|
|
||||||
void ModuleRtpRtcpImpl::SetCsrcs(const std::vector<uint32_t>& csrcs) {
|
void ModuleRtpRtcpImpl::SetCsrcs(const std::vector<uint32_t>& csrcs) {
|
||||||
rtcp_sender_.SetCsrcs(csrcs);
|
rtcp_sender_.SetCsrcs(csrcs);
|
||||||
rtp_sender_->SetCsrcs(csrcs);
|
rtp_sender_->SetCsrcs(csrcs);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -86,6 +87,8 @@ class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
|
||||||
// Configure SSRC, default is a random number.
|
// Configure SSRC, default is a random number.
|
||||||
void SetSSRC(uint32_t ssrc) override;
|
void SetSSRC(uint32_t ssrc) override;
|
||||||
|
|
||||||
|
void SetMid(const std::string& mid) override;
|
||||||
|
|
||||||
void SetCsrcs(const std::vector<uint32_t>& csrcs) override;
|
void SetCsrcs(const std::vector<uint32_t>& csrcs) override;
|
||||||
|
|
||||||
RTCPSender::FeedbackState GetFeedbackState();
|
RTCPSender::FeedbackState GetFeedbackState();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "modules/rtp_rtcp/source/rtp_sender.h"
|
#include "modules/rtp_rtcp/source/rtp_sender.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
|
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
|
||||||
|
@ -328,6 +329,9 @@ int RTPSender::RtxStatus() const {
|
||||||
void RTPSender::SetRtxSsrc(uint32_t ssrc) {
|
void RTPSender::SetRtxSsrc(uint32_t ssrc) {
|
||||||
rtc::CritScope lock(&send_critsect_);
|
rtc::CritScope lock(&send_critsect_);
|
||||||
ssrc_rtx_.emplace(ssrc);
|
ssrc_rtx_.emplace(ssrc);
|
||||||
|
if (mid_oracle_rtx_) {
|
||||||
|
mid_oracle_rtx_->SetSsrc(ssrc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RTPSender::RtxSsrc() const {
|
uint32_t RTPSender::RtxSsrc() const {
|
||||||
|
@ -727,6 +731,16 @@ void RTPSender::OnReceivedNack(
|
||||||
void RTPSender::OnReceivedRtcpReportBlocks(
|
void RTPSender::OnReceivedRtcpReportBlocks(
|
||||||
const ReportBlockList& report_blocks) {
|
const ReportBlockList& report_blocks) {
|
||||||
playout_delay_oracle_.OnReceivedRtcpReportBlocks(report_blocks);
|
playout_delay_oracle_.OnReceivedRtcpReportBlocks(report_blocks);
|
||||||
|
|
||||||
|
{
|
||||||
|
rtc::CritScope lock(&send_critsect_);
|
||||||
|
if (mid_oracle_) {
|
||||||
|
mid_oracle_->OnReceivedRtcpReportBlocks(report_blocks);
|
||||||
|
}
|
||||||
|
if (mid_oracle_rtx_) {
|
||||||
|
mid_oracle_rtx_->OnReceivedRtcpReportBlocks(report_blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from pacer when we can send the packet.
|
// Called from pacer when we can send the packet.
|
||||||
|
@ -1073,6 +1087,10 @@ std::unique_ptr<RtpPacketToSend> RTPSender::AllocatePacket() const {
|
||||||
packet->SetExtension<PlayoutDelayLimits>(
|
packet->SetExtension<PlayoutDelayLimits>(
|
||||||
playout_delay_oracle_.playout_delay());
|
playout_delay_oracle_.playout_delay());
|
||||||
}
|
}
|
||||||
|
if (mid_oracle_ && mid_oracle_->send_mid()) {
|
||||||
|
// This is a no-op if the MID header extension is not registered.
|
||||||
|
packet->SetExtension<RtpMid>(mid_oracle_->mid());
|
||||||
|
}
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1145,6 +1163,9 @@ void RTPSender::SetSSRC(uint32_t ssrc) {
|
||||||
if (!sequence_number_forced_) {
|
if (!sequence_number_forced_) {
|
||||||
sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
|
sequence_number_ = random_.Rand(1, kMaxInitRtpSeqNumber);
|
||||||
}
|
}
|
||||||
|
if (mid_oracle_) {
|
||||||
|
mid_oracle_->SetSsrc(ssrc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RTPSender::SSRC() const {
|
uint32_t RTPSender::SSRC() const {
|
||||||
|
@ -1153,6 +1174,33 @@ uint32_t RTPSender::SSRC() const {
|
||||||
return *ssrc_;
|
return *ssrc_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RTPSender::SetMid(const std::string& mid) {
|
||||||
|
// This is configured via the API.
|
||||||
|
rtc::CritScope lock(&send_critsect_);
|
||||||
|
|
||||||
|
// Cannot change MID once sending.
|
||||||
|
RTC_DCHECK(!sending_media_);
|
||||||
|
|
||||||
|
// Cannot change the MID if it is already set.
|
||||||
|
if (mid_oracle_) {
|
||||||
|
RTC_DCHECK_EQ(mid_oracle_->mid(), mid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mid_oracle_rtx_) {
|
||||||
|
RTC_DCHECK_EQ(mid_oracle_rtx_->mid(), mid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mid_oracle_ = rtc::MakeUnique<MidOracle>(mid);
|
||||||
|
if (ssrc_) {
|
||||||
|
mid_oracle_->SetSsrc(*ssrc_);
|
||||||
|
}
|
||||||
|
mid_oracle_rtx_ = rtc::MakeUnique<MidOracle>(mid);
|
||||||
|
if (ssrc_rtx_) {
|
||||||
|
mid_oracle_rtx_->SetSsrc(*ssrc_rtx_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rtc::Optional<uint32_t> RTPSender::FlexfecSsrc() const {
|
rtc::Optional<uint32_t> RTPSender::FlexfecSsrc() const {
|
||||||
if (video_) {
|
if (video_) {
|
||||||
return video_->FlexfecSsrc();
|
return video_->FlexfecSsrc();
|
||||||
|
@ -1236,6 +1284,12 @@ std::unique_ptr<RtpPacketToSend> RTPSender::BuildRtxPacket(
|
||||||
|
|
||||||
// Replace SSRC.
|
// Replace SSRC.
|
||||||
rtx_packet->SetSsrc(*ssrc_rtx_);
|
rtx_packet->SetSsrc(*ssrc_rtx_);
|
||||||
|
|
||||||
|
// Possibly include the MID header extension.
|
||||||
|
if (mid_oracle_rtx_ && mid_oracle_rtx_->send_mid()) {
|
||||||
|
// This is a no-op if the MID header extension is not registered.
|
||||||
|
rtx_packet->SetExtension<RtpMid>(mid_oracle_rtx_->mid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* rtx_payload =
|
uint8_t* rtx_payload =
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
#include "modules/rtp_rtcp/include/flexfec_sender.h"
|
#include "modules/rtp_rtcp/include/flexfec_sender.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
|
#include "modules/rtp_rtcp/source/mid_oracle.h"
|
||||||
#include "modules/rtp_rtcp/source/playout_delay_oracle.h"
|
#include "modules/rtp_rtcp/source/playout_delay_oracle.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_packet_history.h"
|
#include "modules/rtp_rtcp/source/rtp_packet_history.h"
|
||||||
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
||||||
|
@ -92,6 +94,8 @@ class RTPSender {
|
||||||
|
|
||||||
void SetSSRC(uint32_t ssrc);
|
void SetSSRC(uint32_t ssrc);
|
||||||
|
|
||||||
|
void SetMid(const std::string& mid);
|
||||||
|
|
||||||
uint16_t SequenceNumber() const;
|
uint16_t SequenceNumber() const;
|
||||||
void SetSequenceNumber(uint16_t seq);
|
void SetSequenceNumber(uint16_t seq);
|
||||||
|
|
||||||
|
@ -134,7 +138,8 @@ class RTPSender {
|
||||||
|
|
||||||
int32_t ReSendPacket(uint16_t packet_id);
|
int32_t ReSendPacket(uint16_t packet_id);
|
||||||
|
|
||||||
// Feedback to decide when to stop sending playout delay.
|
// Feedback to decide when to stop sending the playout delay and MID header
|
||||||
|
// extensions.
|
||||||
void OnReceivedRtcpReportBlocks(const ReportBlockList& report_blocks);
|
void OnReceivedRtcpReportBlocks(const ReportBlockList& report_blocks);
|
||||||
|
|
||||||
// RTX.
|
// RTX.
|
||||||
|
@ -316,6 +321,7 @@ class RTPSender {
|
||||||
// Must be explicitly set by the application, use of rtc::Optional
|
// Must be explicitly set by the application, use of rtc::Optional
|
||||||
// only to keep track of correct use.
|
// only to keep track of correct use.
|
||||||
rtc::Optional<uint32_t> ssrc_ RTC_GUARDED_BY(send_critsect_);
|
rtc::Optional<uint32_t> ssrc_ RTC_GUARDED_BY(send_critsect_);
|
||||||
|
std::unique_ptr<MidOracle> mid_oracle_ RTC_GUARDED_BY(send_critsect_);
|
||||||
uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(send_critsect_);
|
uint32_t last_rtp_timestamp_ RTC_GUARDED_BY(send_critsect_);
|
||||||
int64_t capture_time_ms_ RTC_GUARDED_BY(send_critsect_);
|
int64_t capture_time_ms_ RTC_GUARDED_BY(send_critsect_);
|
||||||
int64_t last_timestamp_time_ms_ RTC_GUARDED_BY(send_critsect_);
|
int64_t last_timestamp_time_ms_ RTC_GUARDED_BY(send_critsect_);
|
||||||
|
@ -324,6 +330,7 @@ class RTPSender {
|
||||||
std::vector<uint32_t> csrcs_ RTC_GUARDED_BY(send_critsect_);
|
std::vector<uint32_t> csrcs_ RTC_GUARDED_BY(send_critsect_);
|
||||||
int rtx_ RTC_GUARDED_BY(send_critsect_);
|
int rtx_ RTC_GUARDED_BY(send_critsect_);
|
||||||
rtc::Optional<uint32_t> ssrc_rtx_ RTC_GUARDED_BY(send_critsect_);
|
rtc::Optional<uint32_t> ssrc_rtx_ RTC_GUARDED_BY(send_critsect_);
|
||||||
|
std::unique_ptr<MidOracle> mid_oracle_rtx_ RTC_GUARDED_BY(send_critsect_);
|
||||||
// Mapping rtx_payload_type_map_[associated] = rtx.
|
// Mapping rtx_payload_type_map_[associated] = rtx.
|
||||||
std::map<int8_t, int8_t> rtx_payload_type_map_ RTC_GUARDED_BY(send_critsect_);
|
std::map<int8_t, int8_t> rtx_payload_type_map_ RTC_GUARDED_BY(send_critsect_);
|
||||||
size_t rtp_overhead_bytes_per_packet_ RTC_GUARDED_BY(send_critsect_);
|
size_t rtp_overhead_bytes_per_packet_ RTC_GUARDED_BY(send_critsect_);
|
||||||
|
|
|
@ -43,6 +43,7 @@ const int kTransmissionTimeOffsetExtensionId = 1;
|
||||||
const int kAbsoluteSendTimeExtensionId = 14;
|
const int kAbsoluteSendTimeExtensionId = 14;
|
||||||
const int kTransportSequenceNumberExtensionId = 13;
|
const int kTransportSequenceNumberExtensionId = 13;
|
||||||
const int kVideoTimingExtensionId = 12;
|
const int kVideoTimingExtensionId = 12;
|
||||||
|
const int kMidExtensionId = 11;
|
||||||
const int kPayload = 100;
|
const int kPayload = 100;
|
||||||
const int kRtxPayload = 98;
|
const int kRtxPayload = 98;
|
||||||
const uint32_t kTimestamp = 10;
|
const uint32_t kTimestamp = 10;
|
||||||
|
@ -83,6 +84,7 @@ class LoopbackTransportTest : public webrtc::Transport {
|
||||||
kAudioLevelExtensionId);
|
kAudioLevelExtensionId);
|
||||||
receivers_extensions_.Register(kRtpExtensionVideoTiming,
|
receivers_extensions_.Register(kRtpExtensionVideoTiming,
|
||||||
kVideoTimingExtensionId);
|
kVideoTimingExtensionId);
|
||||||
|
receivers_extensions_.Register(kRtpExtensionMid, kMidExtensionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendRtp(const uint8_t* data,
|
bool SendRtp(const uint8_t* data,
|
||||||
|
@ -1171,6 +1173,30 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) {
|
||||||
EXPECT_EQ(kFlexfecSsrc, flexfec_packet.Ssrc());
|
EXPECT_EQ(kFlexfecSsrc, flexfec_packet.Ssrc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that the MID header extension is included on sent packets when
|
||||||
|
// configured.
|
||||||
|
TEST_P(RtpSenderTestWithoutPacer, MidIncludedOnSentPackets) {
|
||||||
|
const char kMid[] = "mid";
|
||||||
|
|
||||||
|
// Register MID header extension and set the MID for the RTPSender.
|
||||||
|
rtp_sender_->SetSendingMediaStatus(false);
|
||||||
|
rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionMid, kMidExtensionId);
|
||||||
|
rtp_sender_->SetMid(kMid);
|
||||||
|
rtp_sender_->SetSendingMediaStatus(true);
|
||||||
|
|
||||||
|
// Send a couple packets.
|
||||||
|
SendGenericPayload();
|
||||||
|
SendGenericPayload();
|
||||||
|
|
||||||
|
// Expect both packets to have the MID set.
|
||||||
|
ASSERT_EQ(2u, transport_.sent_packets_.size());
|
||||||
|
for (const RtpPacketReceived& packet : transport_.sent_packets_) {
|
||||||
|
std::string mid;
|
||||||
|
ASSERT_TRUE(packet.GetExtension<RtpMid>(&mid));
|
||||||
|
EXPECT_EQ(kMid, mid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(RtpSenderTest, FecOverheadRate) {
|
TEST_P(RtpSenderTest, FecOverheadRate) {
|
||||||
constexpr int kFlexfecPayloadType = 118;
|
constexpr int kFlexfecPayloadType = 118;
|
||||||
constexpr uint32_t kMediaSsrc = 1234;
|
constexpr uint32_t kMediaSsrc = 1234;
|
||||||
|
|
|
@ -147,6 +147,8 @@ std::unique_ptr<FlexfecSender> MaybeCreateFlexfecSender(
|
||||||
}
|
}
|
||||||
|
|
||||||
RTC_DCHECK_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
|
RTC_DCHECK_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
|
||||||
|
// TODO(bugs.webrtc.org/4050): Pass down MID value once it is exposed in the
|
||||||
|
// API.
|
||||||
return std::unique_ptr<FlexfecSender>(new FlexfecSender(
|
return std::unique_ptr<FlexfecSender>(new FlexfecSender(
|
||||||
config.rtp.flexfec.payload_type, config.rtp.flexfec.ssrc,
|
config.rtp.flexfec.payload_type, config.rtp.flexfec.ssrc,
|
||||||
config.rtp.flexfec.protected_media_ssrcs[0], config.rtp.extensions,
|
config.rtp.flexfec.protected_media_ssrcs[0], config.rtp.extensions,
|
||||||
|
|
Loading…
Reference in a new issue