Change RtcpPacket::PacketReadyCallback to rtc::FunctionView

from interface


Bug: webrtc:5565
Change-Id: I2df5d7a0554b938888581f1c73dbdb8b85c387cc
Reviewed-on: https://webrtc-review.googlesource.com/8680
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21136}
This commit is contained in:
Danil Chapovalov
2017-12-07 10:15:53 +01:00
committed by Commit Bot
parent f1061c2d90
commit 5c3cc41cef
39 changed files with 158 additions and 209 deletions

View File

@ -10,6 +10,7 @@
#include "modules/rtp_rtcp/source/rtcp_packet.h" #include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
namespace webrtc { namespace webrtc {
@ -28,9 +29,9 @@ rtc::Buffer RtcpPacket::Build() const {
return packet; return packet;
} }
bool RtcpPacket::BuildExternalBuffer(uint8_t* buffer, bool RtcpPacket::Build(size_t max_length, PacketReadyCallback callback) const {
size_t max_length, RTC_CHECK_LE(max_length, IP_PACKET_SIZE);
PacketReadyCallback* callback) const { uint8_t buffer[IP_PACKET_SIZE];
size_t index = 0; size_t index = 0;
if (!Create(buffer, &index, max_length, callback)) if (!Create(buffer, &index, max_length, callback))
return false; return false;
@ -39,11 +40,11 @@ bool RtcpPacket::BuildExternalBuffer(uint8_t* buffer,
bool RtcpPacket::OnBufferFull(uint8_t* packet, bool RtcpPacket::OnBufferFull(uint8_t* packet,
size_t* index, size_t* index,
PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
if (*index == 0) if (*index == 0)
return false; return false;
RTC_DCHECK(callback) << "Fragmentation not supported."; RTC_DCHECK(callback) << "Fragmentation not supported.";
callback->OnPacketReady(packet, *index); callback(rtc::ArrayView<const uint8_t>(packet, *index));
*index = 0; *index = 0;
return true; return true;
} }

View File

@ -13,6 +13,7 @@
#include "rtc_base/basictypes.h" #include "rtc_base/basictypes.h"
#include "rtc_base/buffer.h" #include "rtc_base/buffer.h"
#include "rtc_base/function_view.h"
namespace webrtc { namespace webrtc {
namespace rtcp { namespace rtcp {
@ -49,14 +50,8 @@ class RtcpPacket {
// not contain all data in this RtcpPacket; if a packet cannot fit in // not contain all data in this RtcpPacket; if a packet cannot fit in
// max_length bytes, it will be fragmented and multiple calls to this // max_length bytes, it will be fragmented and multiple calls to this
// callback will be made. // callback will be made.
class PacketReadyCallback { using PacketReadyCallback =
public: rtc::FunctionView<void(rtc::ArrayView<const uint8_t> packet)>;
virtual void OnPacketReady(uint8_t* data, size_t length) = 0;
protected:
PacketReadyCallback() {}
virtual ~PacketReadyCallback() {}
};
virtual ~RtcpPacket() {} virtual ~RtcpPacket() {}
@ -64,11 +59,8 @@ class RtcpPacket {
// fragmentation using BlockLength() to allocate big enough buffer. // fragmentation using BlockLength() to allocate big enough buffer.
rtc::Buffer Build() const; rtc::Buffer Build() const;
// Returns true if call to Create succeeded. Provided buffer reference // Returns true if call to Create succeeded.
// will be used for all calls to callback. bool Build(size_t max_length, PacketReadyCallback callback) const;
bool BuildExternalBuffer(uint8_t* buffer,
size_t max_length,
PacketReadyCallback* callback) const;
// Size of this packet in bytes (including headers). // Size of this packet in bytes (including headers).
virtual size_t BlockLength() const = 0; virtual size_t BlockLength() const = 0;
@ -79,7 +71,7 @@ class RtcpPacket {
virtual bool Create(uint8_t* packet, virtual bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
PacketReadyCallback* callback) const = 0; PacketReadyCallback callback) const = 0;
protected: protected:
// Size of the rtcp common header. // Size of the rtcp common header.
@ -94,7 +86,7 @@ class RtcpPacket {
bool OnBufferFull(uint8_t* packet, bool OnBufferFull(uint8_t* packet,
size_t* index, size_t* index,
PacketReadyCallback* callback) const; PacketReadyCallback callback) const;
// Size of the rtcp packet as written in header. // Size of the rtcp packet as written in header.
size_t HeaderLength() const; size_t HeaderLength() const;
}; };

View File

@ -77,7 +77,7 @@ size_t App::BlockLength() const {
bool App::Create(uint8_t* packet, bool App::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -43,7 +43,7 @@ class App : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static constexpr size_t kAppBaseLength = 8; // Ssrc and Name. static constexpr size_t kAppBaseLength = 8; // Ssrc and Name.

View File

@ -80,7 +80,7 @@ bool Bye::Parse(const CommonHeader& packet) {
bool Bye::Create(uint8_t* packet, bool Bye::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -44,7 +44,7 @@ class Bye : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC. static const int kMaxNumberOfCsrcs = 0x1f - 1; // First item is sender SSRC.

View File

@ -27,7 +27,7 @@ void CompoundPacket::Append(RtcpPacket* packet) {
bool CompoundPacket::Create(uint8_t* packet, bool CompoundPacket::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
for (RtcpPacket* appended : appended_packets_) { for (RtcpPacket* appended : appended_packets_) {
if (!appended->Create(packet, index, max_length, callback)) if (!appended->Create(packet, index, max_length, callback))
return false; return false;

View File

@ -34,7 +34,7 @@ class CompoundPacket : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
protected: protected:
std::vector<RtcpPacket*> appended_packets_; std::vector<RtcpPacket*> appended_packets_;

View File

@ -15,9 +15,13 @@
#include "modules/rtp_rtcp/source/rtcp_packet/fir.h" #include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
#include "test/rtcp_packet_parser.h" #include "test/rtcp_packet_parser.h"
using ::testing::_;
using ::testing::Invoke;
using ::testing::MockFunction;
using webrtc::rtcp::Bye; using webrtc::rtcp::Bye;
using webrtc::rtcp::CompoundPacket; using webrtc::rtcp::CompoundPacket;
using webrtc::rtcp::Fir; using webrtc::rtcp::Fir;
@ -95,23 +99,18 @@ TEST(RtcpCompoundPacketTest, BuildWithInputBuffer) {
const size_t kReportBlockLength = 24; const size_t kReportBlockLength = 24;
const size_t kFirLength = 20; const size_t kFirLength = 20;
class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
public:
void OnPacketReady(uint8_t* data, size_t length) override {
RtcpPacketParser parser;
parser.Parse(data, length);
EXPECT_EQ(1, parser.receiver_report()->num_packets());
EXPECT_EQ(1u, parser.receiver_report()->report_blocks().size());
EXPECT_EQ(1, parser.fir()->num_packets());
++packets_created_;
}
int packets_created_ = 0;
} verifier;
const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength; const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength;
uint8_t buffer[kBufferSize]; MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
EXPECT_TRUE(compound.BuildExternalBuffer(buffer, kBufferSize, &verifier)); EXPECT_CALL(callback, Call(_))
EXPECT_EQ(1, verifier.packets_created_); .WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
RtcpPacketParser parser;
parser.Parse(packet.data(), packet.size());
EXPECT_EQ(1, parser.receiver_report()->num_packets());
EXPECT_EQ(1u, parser.receiver_report()->report_blocks().size());
EXPECT_EQ(1, parser.fir()->num_packets());
}));
EXPECT_TRUE(compound.Build(kBufferSize, callback.AsStdFunction()));
} }
TEST(RtcpCompoundPacketTest, BuildWithTooSmallBuffer_FragmentedSend) { TEST(RtcpCompoundPacketTest, BuildWithTooSmallBuffer_FragmentedSend) {
@ -128,34 +127,25 @@ TEST(RtcpCompoundPacketTest, BuildWithTooSmallBuffer_FragmentedSend) {
const size_t kRrLength = 8; const size_t kRrLength = 8;
const size_t kReportBlockLength = 24; const size_t kReportBlockLength = 24;
class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
public:
void OnPacketReady(uint8_t* data, size_t length) override {
RtcpPacketParser parser;
parser.Parse(data, length);
switch (packets_created_++) {
case 0:
EXPECT_EQ(1, parser.receiver_report()->num_packets());
EXPECT_EQ(1U, parser.receiver_report()->report_blocks().size());
EXPECT_EQ(0, parser.fir()->num_packets());
break;
case 1:
EXPECT_EQ(0, parser.receiver_report()->num_packets());
EXPECT_EQ(0U, parser.receiver_report()->report_blocks().size());
EXPECT_EQ(1, parser.fir()->num_packets());
break;
default:
ADD_FAILURE() << "OnPacketReady not expected to be called "
<< packets_created_ << " times.";
}
}
int packets_created_ = 0;
} verifier;
const size_t kBufferSize = kRrLength + kReportBlockLength; const size_t kBufferSize = kRrLength + kReportBlockLength;
uint8_t buffer[kBufferSize]; MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
EXPECT_TRUE(compound.BuildExternalBuffer(buffer, kBufferSize, &verifier)); EXPECT_CALL(callback, Call(_))
EXPECT_EQ(2, verifier.packets_created_); .WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
RtcpPacketParser parser;
parser.Parse(packet.data(), packet.size());
EXPECT_EQ(1, parser.receiver_report()->num_packets());
EXPECT_EQ(1U, parser.receiver_report()->report_blocks().size());
EXPECT_EQ(0, parser.fir()->num_packets());
}))
.WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
RtcpPacketParser parser;
parser.Parse(packet.data(), packet.size());
EXPECT_EQ(0, parser.receiver_report()->num_packets());
EXPECT_EQ(0U, parser.receiver_report()->report_blocks().size());
EXPECT_EQ(1, parser.fir()->num_packets());
}));
EXPECT_TRUE(compound.Build(kBufferSize, callback.AsStdFunction()));
} }
} // namespace webrtc } // namespace webrtc

View File

@ -75,11 +75,10 @@ size_t ExtendedJitterReport::BlockLength() const {
return kHeaderLength + kJitterSizeBytes * inter_arrival_jitters_.size(); return kHeaderLength + kJitterSizeBytes * inter_arrival_jitters_.size();
} }
bool ExtendedJitterReport::Create( bool ExtendedJitterReport::Create(uint8_t* packet,
uint8_t* packet, size_t* index,
size_t* index, size_t max_length,
size_t max_length, PacketReadyCallback callback) const {
RtcpPacket::PacketReadyCallback* callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -41,7 +41,7 @@ class ExtendedJitterReport : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static constexpr size_t kJitterSizeBytes = 4; static constexpr size_t kJitterSizeBytes = 4;

View File

@ -129,7 +129,7 @@ size_t ExtendedReports::BlockLength() const {
bool ExtendedReports::Create(uint8_t* packet, bool ExtendedReports::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -57,7 +57,7 @@ class ExtendedReports : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static constexpr size_t kXrBaseLength = 4; static constexpr size_t kXrBaseLength = 4;

View File

@ -84,7 +84,7 @@ size_t Fir::BlockLength() const {
bool Fir::Create(uint8_t* packet, bool Fir::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
RTC_DCHECK(!items_.empty()); RTC_DCHECK(!items_.empty());
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))

View File

@ -46,7 +46,7 @@ class Fir : public Psfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static constexpr size_t kFciLength = 8; static constexpr size_t kFciLength = 8;

View File

@ -84,7 +84,7 @@ size_t Nack::BlockLength() const {
bool Nack::Create(uint8_t* packet, bool Nack::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
RTC_DCHECK(!packed_.empty()); RTC_DCHECK(!packed_.empty());
// If nack list can't fit in packet, try to fragment. // If nack list can't fit in packet, try to fragment.
constexpr size_t kNackHeaderLength = kHeaderLength + kCommonFeedbackLength; constexpr size_t kNackHeaderLength = kHeaderLength + kCommonFeedbackLength;

View File

@ -38,7 +38,7 @@ class Nack : public Rtpfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static constexpr size_t kNackItemLength = 4; static constexpr size_t kNackItemLength = 4;

View File

@ -18,10 +18,12 @@ namespace webrtc {
namespace { namespace {
using ::testing::_; using ::testing::_;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray; using ::testing::ElementsAreArray;
using ::testing::Invoke; using ::testing::Invoke;
using ::testing::make_tuple; using ::testing::MockFunction;
using ::testing::UnorderedElementsAreArray; using ::testing::UnorderedElementsAreArray;
using ::testing::make_tuple;
using ::webrtc::rtcp::Nack; using ::webrtc::rtcp::Nack;
constexpr uint32_t kSenderSsrc = 0x12345678; constexpr uint32_t kSenderSsrc = 0x12345678;
@ -126,30 +128,26 @@ TEST(RtcpPacketNackTest, CreateFragmented) {
nack.SetMediaSsrc(kRemoteSsrc); nack.SetMediaSsrc(kRemoteSsrc);
nack.SetPacketIds(kList, kListLength); nack.SetPacketIds(kList, kListLength);
class MockPacketReadyCallback : public rtcp::RtcpPacket::PacketReadyCallback {
public:
MOCK_METHOD2(OnPacketReady, void(uint8_t*, size_t));
} verifier;
class NackVerifier {
public:
explicit NackVerifier(std::vector<uint16_t> ids) : ids_(ids) {}
void operator()(uint8_t* data, size_t length) {
Nack nack;
EXPECT_TRUE(test::ParseSinglePacket(data, length, &nack));
EXPECT_EQ(kSenderSsrc, nack.sender_ssrc());
EXPECT_EQ(kRemoteSsrc, nack.media_ssrc());
EXPECT_THAT(nack.packet_ids(), ElementsAreArray(ids_));
}
std::vector<uint16_t> ids_;
} packet1({1, 100, 200}), packet2({300, 400});
EXPECT_CALL(verifier, OnPacketReady(_, _))
.WillOnce(Invoke(packet1))
.WillOnce(Invoke(packet2));
const size_t kBufferSize = 12 + (3 * 4); // Fits common header + 3 nack items const size_t kBufferSize = 12 + (3 * 4); // Fits common header + 3 nack items
uint8_t buffer[kBufferSize];
EXPECT_TRUE(nack.BuildExternalBuffer(buffer, kBufferSize, &verifier)); MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
EXPECT_CALL(callback, Call(_))
.WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
Nack nack;
EXPECT_TRUE(test::ParseSinglePacket(packet, &nack));
EXPECT_EQ(kSenderSsrc, nack.sender_ssrc());
EXPECT_EQ(kRemoteSsrc, nack.media_ssrc());
EXPECT_THAT(nack.packet_ids(), ElementsAre(1, 100, 200));
}))
.WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
Nack nack;
EXPECT_TRUE(test::ParseSinglePacket(packet, &nack));
EXPECT_EQ(kSenderSsrc, nack.sender_ssrc());
EXPECT_EQ(kRemoteSsrc, nack.media_ssrc());
EXPECT_THAT(nack.packet_ids(), ElementsAre(300, 400));
}));
EXPECT_TRUE(nack.Build(kBufferSize, callback.AsStdFunction()));
} }
TEST(RtcpPacketNackTest, CreateFailsWithTooSmallBuffer) { TEST(RtcpPacketNackTest, CreateFailsWithTooSmallBuffer) {
@ -159,15 +157,10 @@ TEST(RtcpPacketNackTest, CreateFailsWithTooSmallBuffer) {
nack.SetSenderSsrc(kSenderSsrc); nack.SetSenderSsrc(kSenderSsrc);
nack.SetMediaSsrc(kRemoteSsrc); nack.SetMediaSsrc(kRemoteSsrc);
nack.SetPacketIds(kList, 1); nack.SetPacketIds(kList, 1);
class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
public: MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
void OnPacketReady(uint8_t* data, size_t length) override { EXPECT_CALL(callback, Call(_)).Times(0);
ADD_FAILURE() << "Buffer should be too small."; EXPECT_FALSE(nack.Build(kMinNackBlockSize - 1, callback.AsStdFunction()));
}
} verifier;
uint8_t buffer[kMinNackBlockSize - 1];
EXPECT_FALSE(
nack.BuildExternalBuffer(buffer, kMinNackBlockSize - 1, &verifier));
} }
TEST(RtcpPacketNackTest, ParseFailsWithTooSmallBuffer) { TEST(RtcpPacketNackTest, ParseFailsWithTooSmallBuffer) {

View File

@ -56,7 +56,7 @@ size_t Pli::BlockLength() const {
bool Pli::Create(uint8_t* packet, bool Pli::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -31,7 +31,7 @@ class Pli : public Psfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
}; };
} // namespace rtcp } // namespace rtcp

View File

@ -49,11 +49,10 @@ size_t RapidResyncRequest::BlockLength() const {
return kHeaderLength + kCommonFeedbackLength; return kHeaderLength + kCommonFeedbackLength;
} }
bool RapidResyncRequest::Create( bool RapidResyncRequest::Create(uint8_t* packet,
uint8_t* packet, size_t* index,
size_t* index, size_t max_length,
size_t max_length, PacketReadyCallback callback) const {
RtcpPacket::PacketReadyCallback* callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -34,7 +34,7 @@ class RapidResyncRequest : public Rtpfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
}; };
} // namespace rtcp } // namespace rtcp
} // namespace webrtc } // namespace webrtc

View File

@ -71,7 +71,7 @@ size_t ReceiverReport::BlockLength() const {
bool ReceiverReport::Create(uint8_t* packet, bool ReceiverReport::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -46,7 +46,7 @@ class ReceiverReport : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static const size_t kRrBaseLength = 4; static const size_t kRrBaseLength = 4;

View File

@ -104,7 +104,7 @@ size_t Remb::BlockLength() const {
bool Remb::Create(uint8_t* packet, bool Remb::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -43,7 +43,7 @@ class Remb : public Psfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
static constexpr uint32_t kUniqueIdentifier = 0x52454D42; // 'R' 'E' 'M' 'B'. static constexpr uint32_t kUniqueIdentifier = 0x52454D42; // 'R' 'E' 'M' 'B'.

View File

@ -164,7 +164,7 @@ size_t Sdes::BlockLength() const {
bool Sdes::Create(uint8_t* packet, bool Sdes::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -45,7 +45,7 @@ class Sdes : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
std::vector<Chunk> chunks_; std::vector<Chunk> chunks_;

View File

@ -87,7 +87,7 @@ size_t SenderReport::BlockLength() const {
bool SenderReport::Create(uint8_t* packet, bool SenderReport::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -62,7 +62,7 @@ class SenderReport : public RtcpPacket {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
const size_t kSenderBaseLength = 24; const size_t kSenderBaseLength = 24;

View File

@ -87,7 +87,7 @@ size_t Tmmbn::BlockLength() const {
bool Tmmbn::Create(uint8_t* packet, bool Tmmbn::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))
return false; return false;

View File

@ -42,7 +42,7 @@ class Tmmbn : public Rtpfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
// Media ssrc is unused, shadow base class setter and getter. // Media ssrc is unused, shadow base class setter and getter.

View File

@ -88,7 +88,7 @@ size_t Tmmbr::BlockLength() const {
bool Tmmbr::Create(uint8_t* packet, bool Tmmbr::Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
RTC_DCHECK(!items_.empty()); RTC_DCHECK(!items_.empty());
while (*index + BlockLength() > max_length) { while (*index + BlockLength() > max_length) {
if (!OnBufferFull(packet, index, callback)) if (!OnBufferFull(packet, index, callback))

View File

@ -42,7 +42,7 @@ class Tmmbr : public Rtpfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* index, size_t* index,
size_t max_length, size_t max_length,
RtcpPacket::PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
// Media ssrc is unused, shadow base class setter. // Media ssrc is unused, shadow base class setter.

View File

@ -556,7 +556,7 @@ size_t TransportFeedback::BlockLength() const {
bool TransportFeedback::Create(uint8_t* packet, bool TransportFeedback::Create(uint8_t* packet,
size_t* position, size_t* position,
size_t max_length, size_t max_length,
PacketReadyCallback* callback) const { PacketReadyCallback callback) const {
if (num_seq_no_ == 0) if (num_seq_no_ == 0)
return false; return false;

View File

@ -74,7 +74,7 @@ class TransportFeedback : public Rtpfb {
bool Create(uint8_t* packet, bool Create(uint8_t* packet,
size_t* position, size_t* position,
size_t max_length, size_t max_length,
PacketReadyCallback* callback) const override; PacketReadyCallback callback) const override;
private: private:
// Size in bytes of a delta time in rtcp packet. // Size in bytes of a delta time in rtcp packet.

View File

@ -13,10 +13,12 @@
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
using webrtc::rtcp::ReceiverReport; namespace {
using webrtc::rtcp::ReportBlock;
namespace webrtc { using ::testing::_;
using ::testing::MockFunction;
using ::webrtc::rtcp::ReceiverReport;
using ::webrtc::rtcp::ReportBlock;
const uint32_t kSenderSsrc = 0x12345678; const uint32_t kSenderSsrc = 0x12345678;
@ -30,13 +32,10 @@ TEST(RtcpPacketTest, BuildWithTooSmallBuffer) {
const size_t kReportBlockLength = 24; const size_t kReportBlockLength = 24;
// No packet. // No packet.
class Verifier : public rtcp::RtcpPacket::PacketReadyCallback { MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
void OnPacketReady(uint8_t* data, size_t length) override { EXPECT_CALL(callback, Call(_)).Times(0);
ADD_FAILURE() << "Packet should not fit within max size.";
}
} verifier;
const size_t kBufferSize = kRrLength + kReportBlockLength - 1; const size_t kBufferSize = kRrLength + kReportBlockLength - 1;
uint8_t buffer[kBufferSize]; EXPECT_FALSE(rr.Build(kBufferSize, callback.AsStdFunction()));
EXPECT_FALSE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
} }
} // namespace webrtc
} // namespace

View File

@ -87,37 +87,31 @@ RTCPSender::FeedbackState::FeedbackState()
has_last_xr_rr(false), has_last_xr_rr(false),
module(nullptr) {} module(nullptr) {}
class PacketContainer : public rtcp::CompoundPacket, class PacketContainer : public rtcp::CompoundPacket {
public rtcp::RtcpPacket::PacketReadyCallback {
public: public:
PacketContainer(Transport* transport, RtcEventLog* event_log) PacketContainer(Transport* transport, RtcEventLog* event_log)
: transport_(transport), event_log_(event_log), bytes_sent_(0) {} : transport_(transport), event_log_(event_log) {}
virtual ~PacketContainer() { virtual ~PacketContainer() {
for (RtcpPacket* packet : appended_packets_) for (RtcpPacket* packet : appended_packets_)
delete packet; delete packet;
} }
void OnPacketReady(uint8_t* data, size_t length) override {
if (transport_->SendRtcp(data, length)) {
bytes_sent_ += length;
if (event_log_) {
event_log_->Log(rtc::MakeUnique<RtcEventRtcpPacketOutgoing>(
rtc::ArrayView<const uint8_t>(data, length)));
}
}
}
size_t SendPackets(size_t max_payload_length) { size_t SendPackets(size_t max_payload_length) {
RTC_DCHECK_LE(max_payload_length, IP_PACKET_SIZE); size_t bytes_sent = 0;
uint8_t buffer[IP_PACKET_SIZE]; Build(max_payload_length, [&](rtc::ArrayView<const uint8_t> packet) {
BuildExternalBuffer(buffer, max_payload_length, this); if (transport_->SendRtcp(packet.data(), packet.size())) {
return bytes_sent_; bytes_sent += packet.size();
if (event_log_) {
event_log_->Log(rtc::MakeUnique<RtcEventRtcpPacketOutgoing>(packet));
}
}
});
return bytes_sent;
} }
private: private:
Transport* transport_; Transport* transport_;
RtcEventLog* const event_log_; RtcEventLog* const event_log_;
size_t bytes_sent_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PacketContainer); RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(PacketContainer);
}; };
@ -946,30 +940,6 @@ void RTCPSender::SetVideoBitrateAllocation(const BitrateAllocation& bitrate) {
} }
bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) { bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) {
class Sender : public rtcp::RtcpPacket::PacketReadyCallback {
public:
Sender(Transport* transport, RtcEventLog* event_log)
: transport_(transport), event_log_(event_log), send_failure_(false) {}
void OnPacketReady(uint8_t* data, size_t length) override {
if (transport_->SendRtcp(data, length)) {
if (event_log_) {
event_log_->Log(rtc::MakeUnique<RtcEventRtcpPacketOutgoing>(
rtc::ArrayView<const uint8_t>(data, length)));
}
} else {
send_failure_ = true;
}
}
Transport* const transport_;
RtcEventLog* const event_log_;
bool send_failure_;
// TODO(terelius): We would like to
// RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Sender);
// but we can't because of an incorrect warning (C4822) in MVS 2013.
} sender(transport_, event_log_);
size_t max_packet_size; size_t max_packet_size;
{ {
rtc::CritScope lock(&critical_section_rtcp_sender_); rtc::CritScope lock(&critical_section_rtcp_sender_);
@ -979,9 +949,16 @@ bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) {
} }
RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE); RTC_DCHECK_LE(max_packet_size, IP_PACKET_SIZE);
uint8_t buffer[IP_PACKET_SIZE]; bool send_failure = false;
return packet.BuildExternalBuffer(buffer, max_packet_size, &sender) && auto callback = [&](rtc::ArrayView<const uint8_t> packet) {
!sender.send_failure_; if (transport_->SendRtcp(packet.data(), packet.size())) {
if (event_log_)
event_log_->Log(rtc::MakeUnique<RtcEventRtcpPacketOutgoing>(packet));
} else {
send_failure = true;
}
};
return packet.Build(max_packet_size, callback) && !send_failure;
} }
} // namespace webrtc } // namespace webrtc

View File

@ -50,27 +50,25 @@ struct RtcpTransceiverImpl::RemoteSenderState {
// Compound or Reduced-Size RTCP packet, as defined by RFC 5506 section 2. // Compound or Reduced-Size RTCP packet, as defined by RFC 5506 section 2.
// TODO(danilchap): When in compound mode and packets are so many that several // TODO(danilchap): When in compound mode and packets are so many that several
// compound RTCP packets need to be generated, ensure each packet is compound. // compound RTCP packets need to be generated, ensure each packet is compound.
class RtcpTransceiverImpl::PacketSender class RtcpTransceiverImpl::PacketSender {
: public rtcp::RtcpPacket::PacketReadyCallback {
public: public:
PacketSender(Transport* transport, size_t max_packet_size) PacketSender(rtcp::RtcpPacket::PacketReadyCallback callback,
: transport_(transport), max_packet_size_(max_packet_size) { size_t max_packet_size)
: callback_(callback), max_packet_size_(max_packet_size) {
RTC_CHECK_LE(max_packet_size, IP_PACKET_SIZE); RTC_CHECK_LE(max_packet_size, IP_PACKET_SIZE);
} }
~PacketSender() override { ~PacketSender() { RTC_DCHECK_EQ(index_, 0) << "Unsent rtcp packet."; }
RTC_DCHECK_EQ(index_, 0) << "Unsent rtcp packet.";
}
// Appends a packet to pending compound packet. // Appends a packet to pending compound packet.
// Sends rtcp compound packet if buffer was already full and resets buffer. // Sends rtcp compound packet if buffer was already full and resets buffer.
void AppendPacket(const rtcp::RtcpPacket& packet) { void AppendPacket(const rtcp::RtcpPacket& packet) {
packet.Create(buffer_, &index_, max_packet_size_, this); packet.Create(buffer_, &index_, max_packet_size_, callback_);
} }
// Sends pending rtcp compound packet. // Sends pending rtcp compound packet.
void Send() { void Send() {
if (index_ > 0) { if (index_ > 0) {
OnPacketReady(buffer_, index_); callback_(rtc::ArrayView<const uint8_t>(buffer_, index_));
index_ = 0; index_ = 0;
} }
} }
@ -78,12 +76,7 @@ class RtcpTransceiverImpl::PacketSender
bool IsEmpty() const { return index_ == 0; } bool IsEmpty() const { return index_ == 0; }
private: private:
// Implements RtcpPacket::PacketReadyCallback const rtcp::RtcpPacket::PacketReadyCallback callback_;
void OnPacketReady(uint8_t* data, size_t length) override {
transport_->SendRtcp(data, length);
}
Transport* const transport_;
const size_t max_packet_size_; const size_t max_packet_size_;
size_t index_ = 0; size_t index_ = 0;
uint8_t buffer_[IP_PACKET_SIZE]; uint8_t buffer_[IP_PACKET_SIZE];
@ -284,14 +277,20 @@ void RtcpTransceiverImpl::CreateCompoundPacket(PacketSender* sender) {
} }
void RtcpTransceiverImpl::SendPeriodicCompoundPacket() { void RtcpTransceiverImpl::SendPeriodicCompoundPacket() {
PacketSender sender(config_.outgoing_transport, config_.max_packet_size); auto send_packet = [this](rtc::ArrayView<const uint8_t> packet) {
config_.outgoing_transport->SendRtcp(packet.data(), packet.size());
};
PacketSender sender(send_packet, config_.max_packet_size);
CreateCompoundPacket(&sender); CreateCompoundPacket(&sender);
sender.Send(); sender.Send();
} }
void RtcpTransceiverImpl::SendImmediateFeedback( void RtcpTransceiverImpl::SendImmediateFeedback(
const rtcp::RtcpPacket& rtcp_packet) { const rtcp::RtcpPacket& rtcp_packet) {
PacketSender sender(config_.outgoing_transport, config_.max_packet_size); auto send_packet = [this](rtc::ArrayView<const uint8_t> packet) {
config_.outgoing_transport->SendRtcp(packet.data(), packet.size());
};
PacketSender sender(send_packet, config_.max_packet_size);
// Compound mode requires every sent rtcp packet to be compound, i.e. start // Compound mode requires every sent rtcp packet to be compound, i.e. start
// with a sender or receiver report. // with a sender or receiver report.
if (config_.rtcp_mode == RtcpMode::kCompound) if (config_.rtcp_mode == RtcpMode::kCompound)