From eec21bdae34bd63ebf568430488d6e25d8db9b4a Mon Sep 17 00:00:00 2001 From: jbauch Date: Sun, 20 Mar 2016 06:15:43 -0700 Subject: [PATCH] Reland Use CopyOnWriteBuffer instead of Buffer to avoid unnecessary copies. This CL removes copy and assign support from Buffer and changes various parameters from Buffer to CopyOnWriteBuffer so they can be passed along and copied without actually copying the underlying data. With this changed some parameters to be "const" and fixed an issue when creating a CopyOnWriteBuffer with empty data. BUG=webrtc:5155 Review URL: https://codereview.webrtc.org/1823503002 Cr-Commit-Position: refs/heads/master@{#12062} --- talk/app/webrtc/objc/RTCDataChannel.mm | 4 +- webrtc/api/datachannel.cc | 10 +-- webrtc/api/datachannel.h | 8 +-- webrtc/api/datachannel_unittest.cc | 6 +- webrtc/api/datachannelinterface.h | 6 +- webrtc/api/java/jni/peerconnection_jni.cc | 2 +- webrtc/api/objc/RTCDataChannel.mm | 4 +- .../api/peerconnectioninterface_unittest.cc | 2 +- webrtc/api/sctputils.cc | 36 +++++------ webrtc/api/sctputils.h | 12 ++-- webrtc/api/test/fakedatachannelprovider.h | 2 +- webrtc/api/webrtcsession.cc | 4 +- webrtc/api/webrtcsession.h | 4 +- webrtc/api/webrtcsession_unittest.cc | 2 +- webrtc/base/buffer.cc | 3 - webrtc/base/buffer.h | 9 +-- webrtc/base/buffer_unittest.cc | 17 ------ webrtc/base/copyonwritebuffer.h | 17 +++++- webrtc/base/copyonwritebuffer_unittest.cc | 61 +++++++++++++++++++ webrtc/base/sslfingerprint.h | 4 +- webrtc/media/base/fakemediaengine.h | 16 ++--- webrtc/media/base/fakenetworkinterface.h | 29 +++++---- webrtc/media/base/mediachannel.h | 20 +++--- webrtc/media/base/rtpdataengine.cc | 14 ++--- webrtc/media/base/rtpdataengine.h | 6 +- webrtc/media/base/rtpdataengine_unittest.cc | 18 +++--- webrtc/media/base/videoengine_unittest.h | 34 ++++++----- webrtc/media/engine/webrtcvideoengine2.cc | 20 +++--- webrtc/media/engine/webrtcvideoengine2.h | 4 +- .../engine/webrtcvideoengine2_unittest.cc | 4 +- webrtc/media/engine/webrtcvoiceengine.cc | 22 +++---- webrtc/media/engine/webrtcvoiceengine.h | 10 ++- .../engine/webrtcvoiceengine_unittest.cc | 6 +- webrtc/media/sctp/sctpdataengine.cc | 44 +++++++------ webrtc/media/sctp/sctpdataengine.h | 14 ++--- webrtc/media/sctp/sctpdataengine_unittest.cc | 18 +++--- webrtc/pc/channel.cc | 24 ++++---- webrtc/pc/channel.h | 28 ++++----- webrtc/pc/channel_unittest.cc | 2 +- 39 files changed, 299 insertions(+), 247 deletions(-) diff --git a/talk/app/webrtc/objc/RTCDataChannel.mm b/talk/app/webrtc/objc/RTCDataChannel.mm index 114b916fb4..6cfa5623c4 100644 --- a/talk/app/webrtc/objc/RTCDataChannel.mm +++ b/talk/app/webrtc/objc/RTCDataChannel.mm @@ -153,8 +153,8 @@ std::string StdStringFromNSString(NSString* nsString) { - (instancetype)initWithData:(NSData*)data isBinary:(BOOL)isBinary { NSAssert(data, @"data cannot be nil"); if (self = [super init]) { - rtc::Buffer buffer(reinterpret_cast([data bytes]), - [data length]); + rtc::CopyOnWriteBuffer buffer( + reinterpret_cast([data bytes]), [data length]); _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary)); } return self; diff --git a/webrtc/api/datachannel.cc b/webrtc/api/datachannel.cc index b4dc5d8913..612d7e0b38 100644 --- a/webrtc/api/datachannel.cc +++ b/webrtc/api/datachannel.cc @@ -324,7 +324,7 @@ void DataChannel::OnMessage(rtc::Message* msg) { void DataChannel::OnDataReceived(cricket::DataChannel* channel, const cricket::ReceiveDataParams& params, - const rtc::Buffer& payload) { + const rtc::CopyOnWriteBuffer& payload) { uint32_t expected_ssrc = (data_channel_type_ == cricket::DCT_RTP) ? receive_ssrc_ : config_.id; if (params.ssrc != expected_ssrc) { @@ -422,11 +422,11 @@ void DataChannel::UpdateState() { } if (connected_to_provider_) { if (handshake_state_ == kHandshakeShouldSendOpen) { - rtc::Buffer payload; + rtc::CopyOnWriteBuffer payload; WriteDataChannelOpenMessage(label_, config_, &payload); SendControlMessage(payload); } else if (handshake_state_ == kHandshakeShouldSendAck) { - rtc::Buffer payload; + rtc::CopyOnWriteBuffer payload; WriteDataChannelOpenAckMessage(&payload); SendControlMessage(payload); } @@ -595,11 +595,11 @@ void DataChannel::SendQueuedControlMessages() { } } -void DataChannel::QueueControlMessage(const rtc::Buffer& buffer) { +void DataChannel::QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer) { queued_control_data_.Push(new DataBuffer(buffer, true)); } -bool DataChannel::SendControlMessage(const rtc::Buffer& buffer) { +bool DataChannel::SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) { bool is_open_message = handshake_state_ == kHandshakeShouldSendOpen; ASSERT(data_channel_type_ == cricket::DCT_SCTP && diff --git a/webrtc/api/datachannel.h b/webrtc/api/datachannel.h index 62e3eaf221..b8830be300 100644 --- a/webrtc/api/datachannel.h +++ b/webrtc/api/datachannel.h @@ -31,7 +31,7 @@ class DataChannelProviderInterface { public: // Sends the data to the transport. virtual bool SendData(const cricket::SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) = 0; // Connects to the transport signals. virtual bool ConnectDataChannel(DataChannel* data_channel) = 0; @@ -143,7 +143,7 @@ class DataChannel : public DataChannelInterface, // Sigslots from cricket::DataChannel void OnDataReceived(cricket::DataChannel* channel, const cricket::ReceiveDataParams& params, - const rtc::Buffer& payload); + const rtc::CopyOnWriteBuffer& payload); void OnStreamClosedRemotely(uint32_t sid); // The remote peer request that this channel should be closed. @@ -236,8 +236,8 @@ class DataChannel : public DataChannelInterface, bool QueueSendDataMessage(const DataBuffer& buffer); void SendQueuedControlMessages(); - void QueueControlMessage(const rtc::Buffer& buffer); - bool SendControlMessage(const rtc::Buffer& buffer); + void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer); + bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer); std::string label_; InternalDataChannelInit config_; diff --git a/webrtc/api/datachannel_unittest.cc b/webrtc/api/datachannel_unittest.cc index 880c2aa840..5958ec02f8 100644 --- a/webrtc/api/datachannel_unittest.cc +++ b/webrtc/api/datachannel_unittest.cc @@ -246,7 +246,7 @@ TEST_F(SctpDataChannelTest, SendUnorderedAfterReceivesOpenAck) { cricket::ReceiveDataParams params; params.ssrc = init.id; params.type = cricket::DMT_CONTROL; - rtc::Buffer payload; + rtc::CopyOnWriteBuffer payload; webrtc::WriteDataChannelOpenAckMessage(&payload); dc->OnDataReceived(NULL, params, payload); @@ -404,7 +404,7 @@ TEST_F(SctpDataChannelTest, OpenAckRoleInitialization) { TEST_F(SctpDataChannelTest, ClosedWhenSendBufferFull) { SetChannelReady(); - rtc::Buffer buffer(1024); + rtc::CopyOnWriteBuffer buffer(1024); memset(buffer.data(), 0, buffer.size()); webrtc::DataBuffer packet(buffer, true); @@ -457,7 +457,7 @@ TEST_F(SctpDataChannelTest, RemotePeerRequestClose) { // Tests that the DataChannel is closed if the received buffer is full. TEST_F(SctpDataChannelTest, ClosedWhenReceivedBufferFull) { SetChannelReady(); - rtc::Buffer buffer(1024); + rtc::CopyOnWriteBuffer buffer(1024); memset(buffer.data(), 0, buffer.size()); cricket::ReceiveDataParams params; diff --git a/webrtc/api/datachannelinterface.h b/webrtc/api/datachannelinterface.h index 3d6f711bbf..53c11d4291 100644 --- a/webrtc/api/datachannelinterface.h +++ b/webrtc/api/datachannelinterface.h @@ -17,8 +17,8 @@ #include #include "webrtc/base/basictypes.h" -#include "webrtc/base/buffer.h" #include "webrtc/base/checks.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/refcount.h" @@ -50,7 +50,7 @@ struct DataChannelInit { }; struct DataBuffer { - DataBuffer(const rtc::Buffer& data, bool binary) + DataBuffer(const rtc::CopyOnWriteBuffer& data, bool binary) : data(data), binary(binary) { } @@ -61,7 +61,7 @@ struct DataBuffer { } size_t size() const { return data.size(); } - rtc::Buffer data; + rtc::CopyOnWriteBuffer data; // Indicates if the received data contains UTF-8 or binary data. // Note that the upper layers are left to verify the UTF-8 encoding. // TODO(jiayl): prefer to use an enum instead of a bool. diff --git a/webrtc/api/java/jni/peerconnection_jni.cc b/webrtc/api/java/jni/peerconnection_jni.cc index d614ed6c29..6c8192d8c6 100644 --- a/webrtc/api/java/jni/peerconnection_jni.cc +++ b/webrtc/api/java/jni/peerconnection_jni.cc @@ -893,7 +893,7 @@ JOW(jboolean, DataChannel_sendNative)(JNIEnv* jni, jobject j_dc, jbyteArray data, jboolean binary) { jbyte* bytes = jni->GetByteArrayElements(data, NULL); bool ret = ExtractNativeDC(jni, j_dc)->Send(DataBuffer( - rtc::Buffer(bytes, jni->GetArrayLength(data)), + rtc::CopyOnWriteBuffer(bytes, jni->GetArrayLength(data)), binary)); jni->ReleaseByteArrayElements(data, bytes, JNI_ABORT); return ret; diff --git a/webrtc/api/objc/RTCDataChannel.mm b/webrtc/api/objc/RTCDataChannel.mm index 5778cb5b7a..98599058ee 100644 --- a/webrtc/api/objc/RTCDataChannel.mm +++ b/webrtc/api/objc/RTCDataChannel.mm @@ -53,8 +53,8 @@ class DataChannelDelegateAdapter : public DataChannelObserver { - (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary { NSParameterAssert(data); if (self = [super init]) { - rtc::Buffer buffer(reinterpret_cast(data.bytes), - data.length); + rtc::CopyOnWriteBuffer buffer( + reinterpret_cast(data.bytes), data.length); _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary)); } return self; diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc index 6bff11a4b8..d4678bae0f 100644 --- a/webrtc/api/peerconnectioninterface_unittest.cc +++ b/webrtc/api/peerconnectioninterface_unittest.cc @@ -1400,7 +1400,7 @@ TEST_F(PeerConnectionInterfaceTest, TestSendBinaryOnRtpDataChannel) { EXPECT_EQ(DataChannelInterface::kOpen, data1->state()); EXPECT_EQ(DataChannelInterface::kOpen, data2->state()); - rtc::Buffer buffer("test", 4); + rtc::CopyOnWriteBuffer buffer("test", 4); EXPECT_FALSE(data1->Send(DataBuffer(buffer, true))); } diff --git a/webrtc/api/sctputils.cc b/webrtc/api/sctputils.cc index 1a2c282ff6..f2d1b0f54a 100644 --- a/webrtc/api/sctputils.cc +++ b/webrtc/api/sctputils.cc @@ -10,8 +10,8 @@ #include "webrtc/api/sctputils.h" -#include "webrtc/base/buffer.h" #include "webrtc/base/bytebuffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/logging.h" namespace webrtc { @@ -31,26 +31,27 @@ enum DataChannelOpenMessageChannelType { DCOMCT_UNORDERED_PARTIAL_TIME = 0x82, }; -bool IsOpenMessage(const rtc::Buffer& payload) { +bool IsOpenMessage(const rtc::CopyOnWriteBuffer& payload) { // Format defined at // http://tools.ietf.org/html/draft-jesup-rtcweb-data-protocol-04 - - rtc::ByteBuffer buffer(payload); - uint8_t message_type; - if (!buffer.ReadUInt8(&message_type)) { + if (payload.size() < 1) { LOG(LS_WARNING) << "Could not read OPEN message type."; return false; } + + uint8_t message_type = payload[0]; return message_type == DATA_CHANNEL_OPEN_MESSAGE_TYPE; } -bool ParseDataChannelOpenMessage(const rtc::Buffer& payload, +bool ParseDataChannelOpenMessage(const rtc::CopyOnWriteBuffer& payload, std::string* label, DataChannelInit* config) { // Format defined at // http://tools.ietf.org/html/draft-jesup-rtcweb-data-protocol-04 - rtc::ByteBuffer buffer(payload); + // TODO(jbauch): avoid copying the payload data into the ByteBuffer, see + // https://bugs.chromium.org/p/webrtc/issues/detail?id=5670 + rtc::ByteBuffer buffer(payload.data(), payload.size()); uint8_t message_type; if (!buffer.ReadUInt8(&message_type)) { LOG(LS_WARNING) << "Could not read OPEN message type."; @@ -120,13 +121,13 @@ bool ParseDataChannelOpenMessage(const rtc::Buffer& payload, return true; } -bool ParseDataChannelOpenAckMessage(const rtc::Buffer& payload) { - rtc::ByteBuffer buffer(payload); - uint8_t message_type; - if (!buffer.ReadUInt8(&message_type)) { +bool ParseDataChannelOpenAckMessage(const rtc::CopyOnWriteBuffer& payload) { + if (payload.size() < 1) { LOG(LS_WARNING) << "Could not read OPEN_ACK message type."; return false; } + + uint8_t message_type = payload[0]; if (message_type != DATA_CHANNEL_OPEN_ACK_MESSAGE_TYPE) { LOG(LS_WARNING) << "Data Channel OPEN_ACK message of unexpected type: " << message_type; @@ -137,7 +138,7 @@ bool ParseDataChannelOpenAckMessage(const rtc::Buffer& payload) { bool WriteDataChannelOpenMessage(const std::string& label, const DataChannelInit& config, - rtc::Buffer* payload) { + rtc::CopyOnWriteBuffer* payload) { // Format defined at // http://tools.ietf.org/html/draft-ietf-rtcweb-data-protocol-00#section-6.1 uint8_t channel_type = 0; @@ -168,6 +169,7 @@ bool WriteDataChannelOpenMessage(const std::string& label, rtc::ByteBuffer buffer( NULL, 20 + label.length() + config.protocol.length(), rtc::ByteBuffer::ORDER_NETWORK); + // TODO(tommi): Add error handling and check resulting length. buffer.WriteUInt8(DATA_CHANNEL_OPEN_MESSAGE_TYPE); buffer.WriteUInt8(channel_type); buffer.WriteUInt16(priority); @@ -180,9 +182,9 @@ bool WriteDataChannelOpenMessage(const std::string& label, return true; } -void WriteDataChannelOpenAckMessage(rtc::Buffer* payload) { - rtc::ByteBuffer buffer(rtc::ByteBuffer::ORDER_NETWORK); - buffer.WriteUInt8(DATA_CHANNEL_OPEN_ACK_MESSAGE_TYPE); - payload->SetData(buffer.Data(), buffer.Length()); +void WriteDataChannelOpenAckMessage(rtc::CopyOnWriteBuffer* payload) { + uint8_t data = DATA_CHANNEL_OPEN_ACK_MESSAGE_TYPE; + payload->SetData(&data, sizeof(data)); } + } // namespace webrtc diff --git a/webrtc/api/sctputils.h b/webrtc/api/sctputils.h index ffbade2f0c..2fb194330c 100644 --- a/webrtc/api/sctputils.h +++ b/webrtc/api/sctputils.h @@ -16,26 +16,26 @@ #include "webrtc/api/datachannelinterface.h" namespace rtc { -class Buffer; +class CopyOnWriteBuffer; } // namespace rtc namespace webrtc { struct DataChannelInit; // Read the message type and return true if it's an OPEN message. -bool IsOpenMessage(const rtc::Buffer& payload); +bool IsOpenMessage(const rtc::CopyOnWriteBuffer& payload); -bool ParseDataChannelOpenMessage(const rtc::Buffer& payload, +bool ParseDataChannelOpenMessage(const rtc::CopyOnWriteBuffer& payload, std::string* label, DataChannelInit* config); -bool ParseDataChannelOpenAckMessage(const rtc::Buffer& payload); +bool ParseDataChannelOpenAckMessage(const rtc::CopyOnWriteBuffer& payload); bool WriteDataChannelOpenMessage(const std::string& label, const DataChannelInit& config, - rtc::Buffer* payload); + rtc::CopyOnWriteBuffer* payload); -void WriteDataChannelOpenAckMessage(rtc::Buffer* payload); +void WriteDataChannelOpenAckMessage(rtc::CopyOnWriteBuffer* payload); } // namespace webrtc #endif // WEBRTC_API_SCTPUTILS_H_ diff --git a/webrtc/api/test/fakedatachannelprovider.h b/webrtc/api/test/fakedatachannelprovider.h index 7899c3150a..3404ac1437 100644 --- a/webrtc/api/test/fakedatachannelprovider.h +++ b/webrtc/api/test/fakedatachannelprovider.h @@ -23,7 +23,7 @@ class FakeDataChannelProvider : public webrtc::DataChannelProviderInterface { virtual ~FakeDataChannelProvider() {} bool SendData(const cricket::SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) override { ASSERT(ready_to_send_ && transport_available_); if (send_blocked_) { diff --git a/webrtc/api/webrtcsession.cc b/webrtc/api/webrtcsession.cc index 593d429286..19f5aa4128 100644 --- a/webrtc/api/webrtcsession.cc +++ b/webrtc/api/webrtcsession.cc @@ -1374,7 +1374,7 @@ sigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() { } bool WebRtcSession::SendData(const cricket::SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) { if (!data_channel_) { LOG(LS_ERROR) << "SendData called when data_channel_ is NULL."; @@ -1854,7 +1854,7 @@ void WebRtcSession::OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp) { void WebRtcSession::OnDataChannelMessageReceived( cricket::DataChannel* channel, const cricket::ReceiveDataParams& params, - const rtc::Buffer& payload) { + const rtc::CopyOnWriteBuffer& payload) { RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) { // Received OPEN message; parse and signal that a new data channel should diff --git a/webrtc/api/webrtcsession.h b/webrtc/api/webrtcsession.h index e884678c0f..6164731982 100644 --- a/webrtc/api/webrtcsession.h +++ b/webrtc/api/webrtcsession.h @@ -271,7 +271,7 @@ class WebRtcSession : public AudioProviderInterface, // Implements DataChannelProviderInterface. bool SendData(const cricket::SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, cricket::SendDataResult* result) override; bool ConnectDataChannel(DataChannel* webrtc_data_channel) override; void DisconnectDataChannel(DataChannel* webrtc_data_channel) override; @@ -413,7 +413,7 @@ class WebRtcSession : public AudioProviderInterface, // messages. void OnDataChannelMessageReceived(cricket::DataChannel* channel, const cricket::ReceiveDataParams& params, - const rtc::Buffer& payload); + const rtc::CopyOnWriteBuffer& payload); std::string BadStateErrMsg(State state); void SetIceConnectionState(PeerConnectionInterface::IceConnectionState state); diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc index 77c4854680..18c1a95116 100644 --- a/webrtc/api/webrtcsession_unittest.cc +++ b/webrtc/api/webrtcsession_unittest.cc @@ -4054,7 +4054,7 @@ TEST_P(WebRtcSessionTest, TestSctpDataChannelOpenMessage) { webrtc::DataChannelInit config; config.id = 1; - rtc::Buffer payload; + rtc::CopyOnWriteBuffer payload; webrtc::WriteDataChannelOpenMessage("a", config, &payload); cricket::ReceiveDataParams params; params.ssrc = config.id; diff --git a/webrtc/base/buffer.cc b/webrtc/base/buffer.cc index 3096cc92ba..6051e6db95 100644 --- a/webrtc/base/buffer.cc +++ b/webrtc/base/buffer.cc @@ -19,9 +19,6 @@ Buffer::Buffer() : size_(0), capacity_(0), data_(nullptr) { RTC_DCHECK(IsConsistent()); } -Buffer::Buffer(const Buffer& buf) : Buffer(buf.data(), buf.size()) { -} - Buffer::Buffer(Buffer&& buf) : size_(buf.size()), capacity_(buf.capacity()), diff --git a/webrtc/base/buffer.h b/webrtc/base/buffer.h index 681348d910..f007929a29 100644 --- a/webrtc/base/buffer.h +++ b/webrtc/base/buffer.h @@ -49,7 +49,6 @@ struct ByteType { class Buffer { public: Buffer(); // An empty buffer. - Buffer(const Buffer& buf); // Copy size and contents of an existing buffer. Buffer(Buffer&& buf); // Move contents from an existing buffer. // Construct a buffer with the specified number of uninitialized bytes. @@ -99,12 +98,6 @@ class Buffer { return capacity_; } - Buffer& operator=(const Buffer& buf) { - if (&buf != this) - SetData(buf.data(), buf.size()); - return *this; - } - Buffer& operator=(Buffer&& buf) { RTC_DCHECK(IsConsistent()); RTC_DCHECK(buf.IsConsistent()); @@ -270,6 +263,8 @@ class Buffer { size_t size_; size_t capacity_; std::unique_ptr data_; + + RTC_DISALLOW_COPY_AND_ASSIGN(Buffer); }; } // namespace rtc diff --git a/webrtc/base/buffer_unittest.cc b/webrtc/base/buffer_unittest.cc index 7c654477f3..2f3bcfd606 100644 --- a/webrtc/base/buffer_unittest.cc +++ b/webrtc/base/buffer_unittest.cc @@ -64,23 +64,6 @@ TEST(BufferTest, TestConstructArray) { EXPECT_EQ(0, memcmp(buf.data(), kTestData, 16)); } -TEST(BufferTest, TestConstructCopy) { - Buffer buf1(kTestData), buf2(buf1); - EXPECT_EQ(buf2.size(), 16u); - EXPECT_EQ(buf2.capacity(), 16u); - EXPECT_EQ(0, memcmp(buf2.data(), kTestData, 16)); - EXPECT_NE(buf1.data(), buf2.data()); - EXPECT_EQ(buf1, buf2); -} - -TEST(BufferTest, TestAssign) { - Buffer buf1, buf2(kTestData, sizeof(kTestData), 256); - EXPECT_NE(buf1, buf2); - buf1 = buf2; - EXPECT_EQ(buf1, buf2); - EXPECT_NE(buf1.data(), buf2.data()); -} - TEST(BufferTest, TestSetData) { Buffer buf(kTestData + 4, 7); buf.SetData(kTestData, 9); diff --git a/webrtc/base/copyonwritebuffer.h b/webrtc/base/copyonwritebuffer.h index 17f2710f3e..87f24bf51d 100644 --- a/webrtc/base/copyonwritebuffer.h +++ b/webrtc/base/copyonwritebuffer.h @@ -42,7 +42,9 @@ class CopyOnWriteBuffer { template ::t = 0> CopyOnWriteBuffer(const T* data, size_t size, size_t capacity) : CopyOnWriteBuffer(size, capacity) { - std::memcpy(buffer_->data(), data, size); + if (buffer_) { + std::memcpy(buffer_->data(), data, size); + } } // Construct a buffer from the contents of an array. @@ -123,13 +125,24 @@ class CopyOnWriteBuffer { return !(*this == buf); } + uint8_t& operator[](size_t index) { + RTC_DCHECK_LT(index, size()); + return data()[index]; + } + + uint8_t operator[](size_t index) const { + RTC_DCHECK_LT(index, size()); + return cdata()[index]; + } + // Replace the contents of the buffer. Accepts the same types as the // constructors. template ::t = 0> void SetData(const T* data, size_t size) { RTC_DCHECK(IsConsistent()); if (!buffer_ || !buffer_->HasOneRef()) { - buffer_ = new RefCountedObject(data, size, size); + buffer_ = size > 0 ? new RefCountedObject(data, size) + : nullptr; } else { buffer_->SetData(data, size); } diff --git a/webrtc/base/copyonwritebuffer_unittest.cc b/webrtc/base/copyonwritebuffer_unittest.cc index a95ad67a03..dbf59f7718 100644 --- a/webrtc/base/copyonwritebuffer_unittest.cc +++ b/webrtc/base/copyonwritebuffer_unittest.cc @@ -41,6 +41,13 @@ void EnsureBuffersDontShareData(const CopyOnWriteBuffer& buf1, EXPECT_NE(data1, data2); } +TEST(CopyOnWriteBufferTest, TestCreateEmptyData) { + CopyOnWriteBuffer buf(static_cast(nullptr), 0); + EXPECT_EQ(buf.size(), 0u); + EXPECT_EQ(buf.capacity(), 0u); + EXPECT_EQ(buf.data(), nullptr); +} + TEST(CopyOnWriteBufferTest, TestMoveConstruct) { CopyOnWriteBuffer buf1(kTestData, 3, 10); size_t buf1_size = buf1.size(); @@ -125,6 +132,21 @@ TEST(CopyOnWriteBufferTest, TestSetData) { EnsureBuffersDontShareData(buf1, buf3); const int8_t exp[] = {'f', 'o', 'o', 0x0}; EXPECT_EQ(buf3, CopyOnWriteBuffer(exp)); + + buf2.SetData(static_cast(nullptr), 0u); + EnsureBuffersDontShareData(buf1, buf2); + EXPECT_EQ(buf1.size(), 3u); + EXPECT_EQ(buf1.capacity(), 10u); + EXPECT_EQ(buf2.size(), 0u); + EXPECT_EQ(buf2.capacity(), 0u); +} + +TEST(CopyOnWriteBufferTest, TestSetDataEmpty) { + CopyOnWriteBuffer buf; + buf.SetData(static_cast(nullptr), 0u); + EXPECT_EQ(buf.size(), 0u); + EXPECT_EQ(buf.capacity(), 0u); + EXPECT_EQ(buf.data(), nullptr); } TEST(CopyOnWriteBufferTest, TestEnsureCapacity) { @@ -196,4 +218,43 @@ TEST(CopyOnWriteBufferTest, TestConstDataAccessor) { EXPECT_EQ(data2, cdata1); } +TEST(CopyOnWriteBufferTest, TestBacketRead) { + CopyOnWriteBuffer buf1(kTestData, 3, 10); + CopyOnWriteBuffer buf2(buf1); + + EnsureBuffersShareData(buf1, buf2); + // Non-const reads clone the data if shared. + for (size_t i = 0; i != 3u; ++i) { + EXPECT_EQ(buf1[i], kTestData[i]); + } + EnsureBuffersDontShareData(buf1, buf2); +} + +TEST(CopyOnWriteBufferTest, TestBacketReadConst) { + CopyOnWriteBuffer buf1(kTestData, 3, 10); + CopyOnWriteBuffer buf2(buf1); + + EnsureBuffersShareData(buf1, buf2); + const CopyOnWriteBuffer& cbuf1 = buf1; + for (size_t i = 0; i != 3u; ++i) { + EXPECT_EQ(cbuf1[i], kTestData[i]); + } + EnsureBuffersShareData(buf1, buf2); +} + +TEST(CopyOnWriteBufferTest, TestBacketWrite) { + CopyOnWriteBuffer buf1(kTestData, 3, 10); + CopyOnWriteBuffer buf2(buf1); + + EnsureBuffersShareData(buf1, buf2); + for (size_t i = 0; i != 3u; ++i) { + buf1[i] = kTestData[i] + 1; + } + EXPECT_EQ(buf1.size(), 3u); + EXPECT_EQ(buf1.capacity(), 10u); + EXPECT_EQ(buf2.size(), 3u); + EXPECT_EQ(buf2.capacity(), 10u); + EXPECT_EQ(0, memcmp(buf2.cdata(), kTestData, 3)); +} + } // namespace rtc diff --git a/webrtc/base/sslfingerprint.h b/webrtc/base/sslfingerprint.h index 735238dde6..1413a4cd27 100644 --- a/webrtc/base/sslfingerprint.h +++ b/webrtc/base/sslfingerprint.h @@ -14,7 +14,7 @@ #include #include "webrtc/base/basictypes.h" -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/sslidentity.h" namespace rtc { @@ -44,7 +44,7 @@ struct SSLFingerprint { std::string ToString(); std::string algorithm; - rtc::Buffer digest; + rtc::CopyOnWriteBuffer digest; }; } // namespace rtc diff --git a/webrtc/media/base/fakemediaengine.h b/webrtc/media/base/fakemediaengine.h index 7f9561d25e..af05144b52 100644 --- a/webrtc/media/base/fakemediaengine.h +++ b/webrtc/media/base/fakemediaengine.h @@ -19,7 +19,7 @@ #include #include "webrtc/audio_sink.h" -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/stringutils.h" #include "webrtc/media/base/audiosource.h" #include "webrtc/media/base/mediaengine.h" @@ -58,13 +58,13 @@ template class RtpHelper : public Base { if (!sending_) { return false; } - rtc::Buffer packet(reinterpret_cast(data), len, - kMaxRtpPacketLen); + rtc::CopyOnWriteBuffer packet(reinterpret_cast(data), len, + kMaxRtpPacketLen); return Base::SendPacket(&packet, options); } bool SendRtcp(const void* data, int len) { - rtc::Buffer packet(reinterpret_cast(data), len, - kMaxRtpPacketLen); + rtc::CopyOnWriteBuffer packet(reinterpret_cast(data), len, + kMaxRtpPacketLen); return Base::SendRtcp(&packet, rtc::PacketOptions()); } @@ -205,11 +205,11 @@ template class RtpHelper : public Base { send_extensions_ = extensions; return true; } - virtual void OnPacketReceived(rtc::Buffer* packet, + virtual void OnPacketReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { rtp_packets_.push_back(std::string(packet->data(), packet->size())); } - virtual void OnRtcpReceived(rtc::Buffer* packet, + virtual void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { rtcp_packets_.push_back(std::string(packet->data(), packet->size())); } @@ -609,7 +609,7 @@ class FakeDataMediaChannel : public RtpHelper { } virtual bool SendData(const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result) { if (send_blocked_) { *result = SDR_BLOCK; diff --git a/webrtc/media/base/fakenetworkinterface.h b/webrtc/media/base/fakenetworkinterface.h index d9caac0197..65dac2529b 100644 --- a/webrtc/media/base/fakenetworkinterface.h +++ b/webrtc/media/base/fakenetworkinterface.h @@ -14,8 +14,8 @@ #include #include -#include "webrtc/base/buffer.h" #include "webrtc/base/byteorder.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/criticalsection.h" #include "webrtc/base/dscp.h" #include "webrtc/base/messagehandler.h" @@ -84,12 +84,12 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, } // Note: callers are responsible for deleting the returned buffer. - const rtc::Buffer* GetRtpPacket(int index) { + const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) { rtc::CritScope cs(&crit_); if (index >= NumRtpPackets()) { return NULL; } - return new rtc::Buffer(rtp_packets_[index]); + return new rtc::CopyOnWriteBuffer(rtp_packets_[index]); } int NumRtcpPackets() { @@ -98,12 +98,12 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, } // Note: callers are responsible for deleting the returned buffer. - const rtc::Buffer* GetRtcpPacket(int index) { + const rtc::CopyOnWriteBuffer* GetRtcpPacket(int index) { rtc::CritScope cs(&crit_); if (index >= NumRtcpPackets()) { return NULL; } - return new rtc::Buffer(rtcp_packets_[index]); + return new rtc::CopyOnWriteBuffer(rtcp_packets_[index]); } int sendbuf_size() const { return sendbuf_size_; } @@ -111,7 +111,7 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, rtc::DiffServCodePoint dscp() const { return dscp_; } protected: - virtual bool SendPacket(rtc::Buffer* packet, + virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { rtc::CritScope cs(&crit_); @@ -123,13 +123,12 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, rtp_packets_.push_back(*packet); if (conf_) { - rtc::Buffer buffer_copy(*packet); for (size_t i = 0; i < conf_sent_ssrcs_.size(); ++i) { - if (!SetRtpSsrc(buffer_copy.data(), buffer_copy.size(), + if (!SetRtpSsrc(packet->data(), packet->size(), conf_sent_ssrcs_[i])) { return false; } - PostMessage(ST_RTP, buffer_copy); + PostMessage(ST_RTP, *packet); } } else { PostMessage(ST_RTP, *packet); @@ -137,7 +136,7 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, return true; } - virtual bool SendRtcp(rtc::Buffer* packet, + virtual bool SendRtcp(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { rtc::CritScope cs(&crit_); rtcp_packets_.push_back(*packet); @@ -160,13 +159,13 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, return 0; } - void PostMessage(int id, const rtc::Buffer& packet) { + void PostMessage(int id, const rtc::CopyOnWriteBuffer& packet) { thread_->Post(this, id, rtc::WrapMessageData(packet)); } virtual void OnMessage(rtc::Message* msg) { - rtc::TypedMessageData* msg_data = - static_cast*>( + rtc::TypedMessageData* msg_data = + static_cast*>( msg->pdata); if (dest_) { if (msg->message_id == ST_RTP) { @@ -216,8 +215,8 @@ class FakeNetworkInterface : public MediaChannel::NetworkInterface, // Map to track packet-number that needs to be dropped per ssrc. std::map > drop_map_; rtc::CriticalSection crit_; - std::vector rtp_packets_; - std::vector rtcp_packets_; + std::vector rtp_packets_; + std::vector rtcp_packets_; int sendbuf_size_; int recvbuf_size_; rtc::DiffServCodePoint dscp_; diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index ed565ee5b9..95355c9576 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -17,7 +17,7 @@ #include "webrtc/api/rtpparameters.h" #include "webrtc/base/basictypes.h" -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/dscp.h" #include "webrtc/base/logging.h" #include "webrtc/base/optional.h" @@ -356,9 +356,9 @@ class MediaChannel : public sigslot::has_slots<> { class NetworkInterface { public: enum SocketType { ST_RTP, ST_RTCP }; - virtual bool SendPacket(rtc::Buffer* packet, + virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) = 0; - virtual bool SendRtcp(rtc::Buffer* packet, + virtual bool SendRtcp(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) = 0; virtual int SetOption(SocketType type, rtc::Socket::Option opt, int option) = 0; @@ -380,10 +380,10 @@ class MediaChannel : public sigslot::has_slots<> { return rtc::DSCP_DEFAULT; } // Called when a RTP packet is received. - virtual void OnPacketReceived(rtc::Buffer* packet, + virtual void OnPacketReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) = 0; // Called when a RTCP packet is received. - virtual void OnRtcpReceived(rtc::Buffer* packet, + virtual void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) = 0; // Called when the socket's ability to send has changed. virtual void OnReadyToSend(bool ready) = 0; @@ -408,11 +408,13 @@ class MediaChannel : public sigslot::has_slots<> { } // Base method to send packet using NetworkInterface. - bool SendPacket(rtc::Buffer* packet, const rtc::PacketOptions& options) { + bool SendPacket(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options) { return DoSendPacket(packet, false, options); } - bool SendRtcp(rtc::Buffer* packet, const rtc::PacketOptions& options) { + bool SendRtcp(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options) { return DoSendPacket(packet, true, options); } @@ -441,7 +443,7 @@ class MediaChannel : public sigslot::has_slots<> { return ret; } - bool DoSendPacket(rtc::Buffer* packet, + bool DoSendPacket(rtc::CopyOnWriteBuffer* packet, bool rtcp, const rtc::PacketOptions& options) { rtc::CritScope cs(&network_interface_crit_); @@ -1104,7 +1106,7 @@ class DataMediaChannel : public MediaChannel { virtual bool SendData( const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result = NULL) = 0; // Signals when data is received (params, data, len) sigslot::signal3data(), packet->size(), &header)) { + if (!GetRtpHeader(packet->cdata(), packet->size(), &header)) { // Don't want to log for every corrupt packet. // LOG(LS_WARNING) << "Could not read rtp header from packet of length " // << packet->length() << "."; @@ -215,7 +215,7 @@ void RtpDataMediaChannel::OnPacketReceived( } size_t header_length; - if (!GetRtpHeaderLen(packet->data(), packet->size(), &header_length)) { + if (!GetRtpHeaderLen(packet->cdata(), packet->size(), &header_length)) { // Don't want to log for every corrupt packet. // LOG(LS_WARNING) << "Could not read rtp header" // << length from packet of length " @@ -223,7 +223,7 @@ void RtpDataMediaChannel::OnPacketReceived( return; } const char* data = - packet->data() + header_length + sizeof(kReservedSpace); + packet->cdata() + header_length + sizeof(kReservedSpace); size_t data_len = packet->size() - header_length - sizeof(kReservedSpace); if (!receiving_) { @@ -276,7 +276,7 @@ bool RtpDataMediaChannel::SetMaxSendBandwidth(int bps) { bool RtpDataMediaChannel::SendData( const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result) { if (result) { // If we return true, we'll set this to SDR_SUCCESS. @@ -329,7 +329,7 @@ bool RtpDataMediaChannel::SendData( rtp_clock_by_send_ssrc_[header.ssrc]->Tick( now, &header.seq_num, &header.timestamp); - rtc::Buffer packet(kMinRtpPacketLen, packet_len); + rtc::CopyOnWriteBuffer packet(kMinRtpPacketLen, packet_len); if (!SetRtpHeader(packet.data(), packet.size(), header)) { return false; } diff --git a/webrtc/media/base/rtpdataengine.h b/webrtc/media/base/rtpdataengine.h index 62eebf63c1..0181e65759 100644 --- a/webrtc/media/base/rtpdataengine.h +++ b/webrtc/media/base/rtpdataengine.h @@ -93,14 +93,14 @@ class RtpDataMediaChannel : public DataMediaChannel { receiving_ = receive; return true; } - virtual void OnPacketReceived(rtc::Buffer* packet, + virtual void OnPacketReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time); - virtual void OnRtcpReceived(rtc::Buffer* packet, + virtual void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) {} virtual void OnReadyToSend(bool ready) {} virtual bool SendData( const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result); private: diff --git a/webrtc/media/base/rtpdataengine_unittest.cc b/webrtc/media/base/rtpdataengine_unittest.cc index 2a9b25e277..b5cfd32551 100644 --- a/webrtc/media/base/rtpdataengine_unittest.cc +++ b/webrtc/media/base/rtpdataengine_unittest.cc @@ -11,7 +11,7 @@ #include #include -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/gunit.h" #include "webrtc/base/helpers.h" #include "webrtc/base/ssladapter.h" @@ -124,7 +124,7 @@ class RtpDataMediaChannelTest : public testing::Test { std::string GetSentData(int index) { // Assume RTP header of length 12 - std::unique_ptr packet( + std::unique_ptr packet( iface_->GetRtpPacket(index)); if (packet->size() > 12) { return std::string(packet->data() + 12, packet->size() - 12); @@ -134,7 +134,7 @@ class RtpDataMediaChannelTest : public testing::Test { } cricket::RtpHeader GetSentDataHeader(int index) { - std::unique_ptr packet( + std::unique_ptr packet( iface_->GetRtpPacket(index)); cricket::RtpHeader header; GetRtpHeader(packet->data(), packet->size(), &header); @@ -220,7 +220,7 @@ TEST_F(RtpDataMediaChannelTest, SendData) { cricket::SendDataParams params; params.ssrc = 42; unsigned char data[] = "food"; - rtc::Buffer payload(data, 4); + rtc::CopyOnWriteBuffer payload(data, 4); unsigned char padded_data[] = { 0x00, 0x00, 0x00, 0x00, 'f', 'o', 'o', 'd', @@ -257,7 +257,7 @@ TEST_F(RtpDataMediaChannelTest, SendData) { // Length too large; std::string x10000(10000, 'x'); EXPECT_FALSE(dmc->SendData( - params, rtc::Buffer(x10000.data(), x10000.length()), &result)); + params, rtc::CopyOnWriteBuffer(x10000.data(), x10000.length()), &result)); EXPECT_EQ(cricket::SDR_ERROR, result); EXPECT_FALSE(HasSentData(0)); @@ -325,7 +325,7 @@ TEST_F(RtpDataMediaChannelTest, SendDataMultipleClocks) { params2.ssrc = 42; unsigned char data[] = "foo"; - rtc::Buffer payload(data, 3); + rtc::CopyOnWriteBuffer payload(data, 3); cricket::SendDataResult result; EXPECT_TRUE(dmc1->SendData(params1, payload, &result)); @@ -372,7 +372,7 @@ TEST_F(RtpDataMediaChannelTest, SendDataRate) { cricket::SendDataParams params; params.ssrc = 42; unsigned char data[] = "food"; - rtc::Buffer payload(data, 4); + rtc::CopyOnWriteBuffer payload(data, 4); cricket::SendDataResult result; // With rtp overhead of 32 bytes, each one of our packets is 36 @@ -410,7 +410,7 @@ TEST_F(RtpDataMediaChannelTest, ReceiveData) { 0x00, 0x00, 0x00, 0x00, 'a', 'b', 'c', 'd', 'e' }; - rtc::Buffer packet(data, sizeof(data)); + rtc::CopyOnWriteBuffer packet(data, sizeof(data)); std::unique_ptr dmc(CreateChannel()); @@ -450,7 +450,7 @@ TEST_F(RtpDataMediaChannelTest, InvalidRtpPackets) { unsigned char data[] = { 0x80, 0x65, 0x00, 0x02 }; - rtc::Buffer packet(data, sizeof(data)); + rtc::CopyOnWriteBuffer packet(data, sizeof(data)); std::unique_ptr dmc(CreateChannel()); diff --git a/webrtc/media/base/videoengine_unittest.h b/webrtc/media/base/videoengine_unittest.h index f44e63ac1c..10459db074 100644 --- a/webrtc/media/base/videoengine_unittest.h +++ b/webrtc/media/base/videoengine_unittest.h @@ -258,28 +258,29 @@ class VideoMediaChannelTest : public testing::Test, int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); } - const rtc::Buffer* GetRtpPacket(int index) { + const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) { return network_interface_.GetRtpPacket(index); } int NumRtcpPackets() { return network_interface_.NumRtcpPackets(); } - const rtc::Buffer* GetRtcpPacket(int index) { + const rtc::CopyOnWriteBuffer* GetRtcpPacket(int index) { return network_interface_.GetRtcpPacket(index); } - static int GetPayloadType(const rtc::Buffer* p) { + static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) { int pt = -1; ParseRtpPacket(p, NULL, &pt, NULL, NULL, NULL, NULL); return pt; } - static bool ParseRtpPacket(const rtc::Buffer* p, + static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p, bool* x, int* pt, int* seqnum, uint32_t* tstamp, uint32_t* ssrc, std::string* payload) { - rtc::ByteBuffer buf(*p); + // TODO(jbauch): avoid copying the buffer data into the ByteBuffer + rtc::ByteBuffer buf(p->data(), p->size()); uint8_t u08 = 0; uint16_t u16 = 0; uint32_t u32 = 0; @@ -338,8 +339,9 @@ class VideoMediaChannelTest : public testing::Test, bool CountRtcpFir(int start_index, int stop_index, int* fir_count) { int count = 0; for (int i = start_index; i < stop_index; ++i) { - std::unique_ptr p(GetRtcpPacket(i)); - rtc::ByteBuffer buf(*p); + std::unique_ptr p(GetRtcpPacket(i)); + // TODO(jbauch): avoid copying the buffer data into the ByteBuffer + rtc::ByteBuffer buf(p->data(), p->size()); size_t total_len = 0; // The packet may be a compound RTCP packet. while (total_len < p->size()) { @@ -403,7 +405,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(SetSend(true)); EXPECT_TRUE(SendFrame()); EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); EXPECT_EQ(codec.id, GetPayloadType(p.get())); } // Tests that we can send and receive frames. @@ -414,7 +416,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_EQ(0, renderer_.num_rendered_frames()); EXPECT_TRUE(SendFrame()); EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); EXPECT_EQ(codec.id, GetPayloadType(p.get())); } void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec, @@ -429,7 +431,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_FRAME_WAIT(frame + i * fps, codec.width, codec.height, kTimeout); } } - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); EXPECT_EQ(codec.id, GetPayloadType(p.get())); } @@ -622,7 +624,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(SendFrame()); EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); uint32_t ssrc = 0; - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL); EXPECT_EQ(kSsrc, ssrc); // Packets are being paced out, so these can mismatch between the first and @@ -645,7 +647,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(WaitAndSendFrame(0)); EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); uint32_t ssrc = 0; - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL); EXPECT_EQ(999u, ssrc); // Packets are being paced out, so these can mismatch between the first and @@ -662,7 +664,7 @@ class VideoMediaChannelTest : public testing::Test, uint8_t data1[] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - rtc::Buffer packet1(data1, sizeof(data1)); + rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1)); rtc::SetBE32(packet1.data() + 8, kSsrc); channel_->SetSink(kDefaultReceiveSsrc, NULL); EXPECT_TRUE(SetDefaultCodec()); @@ -695,7 +697,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_GT(NumRtpPackets(), 0); uint32_t ssrc = 0; size_t last_packet = NumRtpPackets() - 1; - std::unique_ptr + std::unique_ptr p(GetRtpPacket(static_cast(last_packet))); ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL); EXPECT_EQ(kSsrc, ssrc); @@ -745,7 +747,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_FRAME_ON_RENDERER_WAIT( renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout); - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get())); EXPECT_EQ(DefaultCodec().width, renderer1.width()); EXPECT_EQ(DefaultCodec().height, renderer1.height()); @@ -1010,7 +1012,7 @@ class VideoMediaChannelTest : public testing::Test, EXPECT_TRUE(WaitAndSendFrame(30)); // Should be rendered. frame_count += 2; EXPECT_FRAME_WAIT(frame_count, codec.width, codec.height, kTimeout); - std::unique_ptr p(GetRtpPacket(0)); + std::unique_ptr p(GetRtpPacket(0)); EXPECT_EQ(codec.id, GetPayloadType(p.get())); // The channel requires 15 fps. diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 83f81f0f42..122edfe092 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -14,7 +14,7 @@ #include #include -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/logging.h" #include "webrtc/base/stringutils.h" #include "webrtc/base/timeutils.h" @@ -1300,14 +1300,14 @@ bool WebRtcVideoChannel2::SetCapturer(uint32_t ssrc, VideoCapturer* capturer) { } void WebRtcVideoChannel2::OnPacketReceived( - rtc::Buffer* packet, + rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, packet_time.not_before); const webrtc::PacketReceiver::DeliveryStatus delivery_result = call_->Receiver()->DeliverPacket( webrtc::MediaType::VIDEO, - reinterpret_cast(packet->data()), packet->size(), + packet->cdata(), packet->size(), webrtc_packet_time); switch (delivery_result) { case webrtc::PacketReceiver::DELIVERY_OK: @@ -1319,12 +1319,12 @@ void WebRtcVideoChannel2::OnPacketReceived( } uint32_t ssrc = 0; - if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { + if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { return; } int payload_type = 0; - if (!GetRtpPayloadType(packet->data(), packet->size(), &payload_type)) { + if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) { return; } @@ -1350,7 +1350,7 @@ void WebRtcVideoChannel2::OnPacketReceived( if (call_->Receiver()->DeliverPacket( webrtc::MediaType::VIDEO, - reinterpret_cast(packet->data()), packet->size(), + packet->cdata(), packet->size(), webrtc_packet_time) != webrtc::PacketReceiver::DELIVERY_OK) { LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; return; @@ -1358,7 +1358,7 @@ void WebRtcVideoChannel2::OnPacketReceived( } void WebRtcVideoChannel2::OnRtcpReceived( - rtc::Buffer* packet, + rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, packet_time.not_before); @@ -1368,7 +1368,7 @@ void WebRtcVideoChannel2::OnRtcpReceived( // logging failures spam the log). call_->Receiver()->DeliverPacket( webrtc::MediaType::VIDEO, - reinterpret_cast(packet->data()), packet->size(), + packet->cdata(), packet->size(), webrtc_packet_time); } @@ -1424,14 +1424,14 @@ void WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len, const webrtc::PacketOptions& options) { - rtc::Buffer packet(data, len, kMaxRtpPacketLen); + rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); rtc::PacketOptions rtc_options; rtc_options.packet_id = options.packet_id; return MediaChannel::SendPacket(&packet, rtc_options); } bool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { - rtc::Buffer packet(data, len, kMaxRtpPacketLen); + rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); return MediaChannel::SendRtcp(&packet, rtc::PacketOptions()); } diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h index 7ffd85343b..171f26ab39 100644 --- a/webrtc/media/engine/webrtcvideoengine2.h +++ b/webrtc/media/engine/webrtcvideoengine2.h @@ -163,9 +163,9 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { bool GetStats(VideoMediaInfo* info) override; bool SetCapturer(uint32_t ssrc, VideoCapturer* capturer) override; - void OnPacketReceived(rtc::Buffer* packet, + void OnPacketReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) override; - void OnRtcpReceived(rtc::Buffer* packet, + void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) override; void OnReadyToSend(bool ready) override; void SetInterface(NetworkInterface* iface) override; diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index 64c691ff8d..fc18721488 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -2959,7 +2959,7 @@ TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) { uint8_t data[kDataLength]; memset(data, 0, sizeof(data)); rtc::SetBE32(&data[8], ssrcs[0]); - rtc::Buffer packet(data, kDataLength); + rtc::CopyOnWriteBuffer packet(data, kDataLength); rtc::PacketTime packet_time; channel_->OnPacketReceived(&packet, packet_time); @@ -3112,7 +3112,7 @@ void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket( rtc::Set8(data, 1, payload_type); rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc); - rtc::Buffer packet(data, kDataLength); + rtc::CopyOnWriteBuffer packet(data, kDataLength); rtc::PacketTime packet_time; channel_->OnPacketReceived(&packet, packet_time); diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index ae2518b73a..4f6ae434c7 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -2237,11 +2237,11 @@ bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, int event, } void WebRtcVoiceMediaChannel::OnPacketReceived( - rtc::Buffer* packet, const rtc::PacketTime& packet_time) { + rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); uint32_t ssrc = 0; - if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { + if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { return; } @@ -2269,8 +2269,7 @@ void WebRtcVoiceMediaChannel::OnPacketReceived( packet_time.not_before); webrtc::PacketReceiver::DeliveryStatus delivery_result = call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, - reinterpret_cast(packet->data()), packet->size(), - webrtc_packet_time); + packet->cdata(), packet->size(), webrtc_packet_time); if (webrtc::PacketReceiver::DELIVERY_OK != delivery_result) { // If the SSRC is unknown here, route it to the default channel, if we have // one. See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5208 @@ -2288,26 +2287,25 @@ void WebRtcVoiceMediaChannel::OnPacketReceived( // Pass it off to the decoder. engine()->voe()->network()->ReceivedRTPPacket( - channel, packet->data(), packet->size(), webrtc_packet_time); + channel, packet->cdata(), packet->size(), webrtc_packet_time); } void WebRtcVoiceMediaChannel::OnRtcpReceived( - rtc::Buffer* packet, const rtc::PacketTime& packet_time) { + rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); // Forward packet to Call as well. const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, packet_time.not_before); call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, - reinterpret_cast(packet->data()), packet->size(), - webrtc_packet_time); + packet->cdata(), packet->size(), webrtc_packet_time); // Sending channels need all RTCP packets with feedback information. // Even sender reports can contain attached report blocks. // Receiving channels need sender reports in order to create // correct receiver reports. int type = 0; - if (!GetRtcpType(packet->data(), packet->size(), &type)) { + if (!GetRtcpType(packet->cdata(), packet->size(), &type)) { LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; return; } @@ -2315,13 +2313,13 @@ void WebRtcVoiceMediaChannel::OnRtcpReceived( // If it is a sender report, find the receive channel that is listening. if (type == kRtcpTypeSR) { uint32_t ssrc = 0; - if (!GetRtcpSsrc(packet->data(), packet->size(), &ssrc)) { + if (!GetRtcpSsrc(packet->cdata(), packet->size(), &ssrc)) { return; } int recv_channel_id = GetReceiveChannelId(ssrc); if (recv_channel_id != -1) { engine()->voe()->network()->ReceivedRTCPPacket( - recv_channel_id, packet->data(), packet->size()); + recv_channel_id, packet->cdata(), packet->size()); } } @@ -2330,7 +2328,7 @@ void WebRtcVoiceMediaChannel::OnRtcpReceived( // will filter out RR internally. for (const auto& ch : send_streams_) { engine()->voe()->network()->ReceivedRTCPPacket( - ch.second->channel(), packet->data(), packet->size()); + ch.second->channel(), packet->cdata(), packet->size()); } } diff --git a/webrtc/media/engine/webrtcvoiceengine.h b/webrtc/media/engine/webrtcvoiceengine.h index 0ccc64908d..a16d0428fe 100644 --- a/webrtc/media/engine/webrtcvoiceengine.h +++ b/webrtc/media/engine/webrtcvoiceengine.h @@ -179,9 +179,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool CanInsertDtmf() override; bool InsertDtmf(uint32_t ssrc, int event, int duration) override; - void OnPacketReceived(rtc::Buffer* packet, + void OnPacketReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) override; - void OnRtcpReceived(rtc::Buffer* packet, + void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) override; void OnReadyToSend(bool ready) override {} bool GetStats(VoiceMediaInfo* info) override; @@ -194,16 +194,14 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool SendRtp(const uint8_t* data, size_t len, const webrtc::PacketOptions& options) override { - rtc::Buffer packet(reinterpret_cast(data), len, - kMaxRtpPacketLen); + rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); rtc::PacketOptions rtc_options; rtc_options.packet_id = options.packet_id; return VoiceMediaChannel::SendPacket(&packet, rtc_options); } bool SendRtcp(const uint8_t* data, size_t len) override { - rtc::Buffer packet(reinterpret_cast(data), len, - kMaxRtpPacketLen); + rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); return VoiceMediaChannel::SendRtcp(&packet, rtc::PacketOptions()); } diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 4fd5918efd..b538c6ff75 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -113,7 +113,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test { EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1)); } void DeliverPacket(const void* data, int len) { - rtc::Buffer packet(reinterpret_cast(data), len); + rtc::CopyOnWriteBuffer packet(reinterpret_cast(data), len); channel_->OnPacketReceived(&packet, rtc::PacketTime()); } void TearDown() override { @@ -3081,14 +3081,14 @@ TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) { TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) { // Test that packets are forwarded to the Call when configured accordingly. const uint32_t kAudioSsrc = 1; - rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame)); + rtc::CopyOnWriteBuffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame)); static const unsigned char kRtcp[] = { 0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp)); + rtc::CopyOnWriteBuffer kRtcpPacket(kRtcp, sizeof(kRtcp)); EXPECT_TRUE(SetupEngineWithSendStream()); cricket::WebRtcVoiceMediaChannel* media_channel = diff --git a/webrtc/media/sctp/sctpdataengine.cc b/webrtc/media/sctp/sctpdataengine.cc index ce0f91ae39..ba3b8f2408 100644 --- a/webrtc/media/sctp/sctpdataengine.cc +++ b/webrtc/media/sctp/sctpdataengine.cc @@ -19,7 +19,7 @@ #include "usrsctplib/usrsctp.h" #include "webrtc/base/arraysize.h" -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/helpers.h" #include "webrtc/base/logging.h" #include "webrtc/base/safe_conversions.h" @@ -89,7 +89,7 @@ std::string ListArray(const uint16_t* array, int num_elems) { namespace cricket { typedef rtc::ScopedMessageData InboundPacketMessage; -typedef rtc::ScopedMessageData OutboundPacketMessage; +typedef rtc::ScopedMessageData OutboundPacketMessage; // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280, // take off 80 bytes for DTLS/TURN/TCP/IP overhead. @@ -103,7 +103,7 @@ enum { }; struct SctpInboundPacket { - rtc::Buffer buffer; + rtc::CopyOnWriteBuffer buffer; ReceiveDataParams params; // The |flags| parameter is used by SCTP to distinguish notification packets // from other types of packets. @@ -165,11 +165,14 @@ static bool GetDataMediaType( } // Log the packet in text2pcap format, if log level is at LS_VERBOSE. -static void VerboseLogPacket(void *data, size_t length, int direction) { +static void VerboseLogPacket(const void *data, size_t length, int direction) { if (LOG_CHECK_LEVEL(LS_VERBOSE) && length > 0) { char *dump_buf; + // Some downstream project uses an older version of usrsctp that expects + // a non-const "void*" as first parameter when dumping the packet, so we + // need to cast the const away here to avoid a compiler error. if ((dump_buf = usrsctp_dumppacket( - data, length, direction)) != NULL) { + const_cast(data), length, direction)) != NULL) { LOG(LS_VERBOSE) << dump_buf; usrsctp_freedumpbuffer(dump_buf); } @@ -189,7 +192,7 @@ static int OnSctpOutboundPacket(void* addr, void* data, size_t length, VerboseLogPacket(addr, length, SCTP_DUMP_OUTBOUND); // Note: We have to copy the data; the caller will delete it. auto* msg = new OutboundPacketMessage( - new rtc::Buffer(reinterpret_cast(data), length)); + new rtc::CopyOnWriteBuffer(reinterpret_cast(data), length)); channel->worker_thread()->Post(channel, MSG_SCTPOUTBOUNDPACKET, msg); return 0; } @@ -581,7 +584,7 @@ bool SctpDataMediaChannel::RemoveRecvStream(uint32_t ssrc) { bool SctpDataMediaChannel::SendData( const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result) { if (result) { // Preset |result| to assume an error. If SendData succeeds, we'll @@ -651,7 +654,7 @@ bool SctpDataMediaChannel::SendData( // Called by network interface when a packet has been received. void SctpDataMediaChannel::OnPacketReceived( - rtc::Buffer* packet, const rtc::PacketTime& packet_time) { + rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { RTC_DCHECK(rtc::Thread::Current() == worker_thread_); LOG(LS_VERBOSE) << debug_name_ << "->OnPacketReceived(...): " << " length=" << packet->size() << ", sending: " << sending_; @@ -663,8 +666,8 @@ void SctpDataMediaChannel::OnPacketReceived( // Pass received packet to SCTP stack. Once processed by usrsctp, the data // will be will be given to the global OnSctpInboundData, and then, // marshalled by a Post and handled with OnMessage. - VerboseLogPacket(packet->data(), packet->size(), SCTP_DUMP_INBOUND); - usrsctp_conninput(this, packet->data(), packet->size(), 0); + VerboseLogPacket(packet->cdata(), packet->size(), SCTP_DUMP_INBOUND); + usrsctp_conninput(this, packet->cdata(), packet->size(), 0); } else { // TODO(ldixon): Consider caching the packet for very slightly better // reliability. @@ -686,25 +689,25 @@ void SctpDataMediaChannel::OnInboundPacketFromSctpToChannel( return; } if (packet->flags & MSG_NOTIFICATION) { - OnNotificationFromSctp(&packet->buffer); + OnNotificationFromSctp(packet->buffer); } else { - OnDataFromSctpToChannel(packet->params, &packet->buffer); + OnDataFromSctpToChannel(packet->params, packet->buffer); } } void SctpDataMediaChannel::OnDataFromSctpToChannel( - const ReceiveDataParams& params, rtc::Buffer* buffer) { + const ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer) { if (receiving_) { LOG(LS_VERBOSE) << debug_name_ << "->OnDataFromSctpToChannel(...): " - << "Posting with length: " << buffer->size() + << "Posting with length: " << buffer.size() << " on stream " << params.ssrc; // Reports all received messages to upper layers, no matter whether the sid // is known. - SignalDataReceived(params, buffer->data(), buffer->size()); + SignalDataReceived(params, buffer.data(), buffer.size()); } else { LOG(LS_WARNING) << debug_name_ << "->OnDataFromSctpToChannel(...): " << "Not receiving packet with sid=" << params.ssrc - << " len=" << buffer->size() << " before SetReceive(true)."; + << " len=" << buffer.size() << " before SetReceive(true)."; } } @@ -767,10 +770,11 @@ bool SctpDataMediaChannel::ResetStream(uint32_t ssrc) { return true; } -void SctpDataMediaChannel::OnNotificationFromSctp(rtc::Buffer* buffer) { +void SctpDataMediaChannel::OnNotificationFromSctp( + const rtc::CopyOnWriteBuffer& buffer) { const sctp_notification& notification = - reinterpret_cast(*buffer->data()); - ASSERT(notification.sn_header.sn_length == buffer->size()); + reinterpret_cast(*buffer.data()); + ASSERT(notification.sn_header.sn_length == buffer.size()); // TODO(ldixon): handle notifications appropriately. switch (notification.sn_header.sn_type) { @@ -963,7 +967,7 @@ bool SctpDataMediaChannel::SetRecvCodecs(const std::vector& codecs) { } void SctpDataMediaChannel::OnPacketFromSctpToNetwork( - rtc::Buffer* buffer) { + rtc::CopyOnWriteBuffer* buffer) { // usrsctp seems to interpret the MTU we give it strangely -- it seems to // give us back packets bigger than that MTU, if only by a fixed amount. // This is that amount that we've observed. diff --git a/webrtc/media/sctp/sctpdataengine.h b/webrtc/media/sctp/sctpdataengine.h index 310d9747ae..8eb99564ca 100644 --- a/webrtc/media/sctp/sctpdataengine.h +++ b/webrtc/media/sctp/sctpdataengine.h @@ -24,7 +24,7 @@ enum PreservedErrno { }; } // namespace cricket -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/media/base/codec.h" #include "webrtc/media/base/mediachannel.h" #include "webrtc/media/base/mediaengine.h" @@ -144,10 +144,10 @@ class SctpDataMediaChannel : public DataMediaChannel, // sctp that will then post the network interface by OnMessage). // Returns true iff successful data somewhere on the send-queue/network. virtual bool SendData(const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result = NULL); // A packet is received from the network interface. Posted to OnMessage. - virtual void OnPacketReceived(rtc::Buffer* packet, + virtual void OnPacketReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time); // Exposed to allow Post call from c-callbacks. @@ -155,7 +155,7 @@ class SctpDataMediaChannel : public DataMediaChannel, // Many of these things are unused by SCTP, but are needed to fulfill // the MediaChannel interface. - virtual void OnRtcpReceived(rtc::Buffer* packet, + virtual void OnRtcpReceived(rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) {} virtual void OnReadyToSend(bool ready) {} @@ -192,12 +192,12 @@ class SctpDataMediaChannel : public DataMediaChannel, bool ResetStream(uint32_t ssrc); // Called by OnMessage to send packet on the network. - void OnPacketFromSctpToNetwork(rtc::Buffer* buffer); + void OnPacketFromSctpToNetwork(rtc::CopyOnWriteBuffer* buffer); // Called by OnMessage to decide what to do with the packet. void OnInboundPacketFromSctpToChannel(SctpInboundPacket* packet); void OnDataFromSctpToChannel(const ReceiveDataParams& params, - rtc::Buffer* buffer); - void OnNotificationFromSctp(rtc::Buffer* buffer); + const rtc::CopyOnWriteBuffer& buffer); + void OnNotificationFromSctp(const rtc::CopyOnWriteBuffer& buffer); void OnNotificationAssocChange(const sctp_assoc_change& change); void OnStreamResetEvent(const struct sctp_stream_reset_event* evt); diff --git a/webrtc/media/sctp/sctpdataengine_unittest.cc b/webrtc/media/sctp/sctpdataengine_unittest.cc index 893d717db7..f18437dc8e 100644 --- a/webrtc/media/sctp/sctpdataengine_unittest.cc +++ b/webrtc/media/sctp/sctpdataengine_unittest.cc @@ -17,7 +17,7 @@ #include #include "webrtc/base/bind.h" -#include "webrtc/base/buffer.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/criticalsection.h" #include "webrtc/base/gunit.h" #include "webrtc/base/helpers.h" @@ -47,13 +47,11 @@ class SctpFakeNetworkInterface : public cricket::MediaChannel::NetworkInterface, protected: // Called to send raw packet down the wire (e.g. SCTP an packet). - virtual bool SendPacket(rtc::Buffer* packet, + virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket"; - // TODO(ldixon): Can/should we use Buffer.TransferTo here? - // Note: this assignment does a deep copy of data from packet. - rtc::Buffer* buffer = new rtc::Buffer(packet->data(), packet->size()); + rtc::CopyOnWriteBuffer* buffer = new rtc::CopyOnWriteBuffer(*packet); thread_->Post(this, MSG_PACKET, rtc::WrapMessageData(buffer)); LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket, Posted message."; return true; @@ -64,8 +62,8 @@ class SctpFakeNetworkInterface : public cricket::MediaChannel::NetworkInterface, // an SCTP packet. virtual void OnMessage(rtc::Message* msg) { LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::OnMessage"; - std::unique_ptr buffer( - static_cast*>( + std::unique_ptr buffer( + static_cast*>( msg->pdata)->data()); if (dest_) { dest_->OnPacketReceived(buffer.get(), rtc::PacketTime()); @@ -76,7 +74,7 @@ class SctpFakeNetworkInterface : public cricket::MediaChannel::NetworkInterface, // Unsupported functions required to exist by NetworkInterface. // TODO(ldixon): Refactor parent NetworkInterface class so these are not // required. They are RTC specific and should be in an appropriate subclass. - virtual bool SendRtcp(rtc::Buffer* packet, + virtual bool SendRtcp(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SendRtcp."; return false; @@ -283,7 +281,7 @@ class SctpDataMediaChannelTest : public testing::Test, cricket::SendDataParams params; params.ssrc = ssrc; - return chan->SendData(params, rtc::Buffer( + return chan->SendData(params, rtc::CopyOnWriteBuffer( &msg[0], msg.length()), result); } @@ -402,7 +400,7 @@ TEST_F(SctpDataMediaChannelTest, SendDataBlocked) { for (size_t i = 0; i < 100; ++i) { channel1()->SendData( - params, rtc::Buffer(&buffer[0], buffer.size()), &result); + params, rtc::CopyOnWriteBuffer(&buffer[0], buffer.size()), &result); if (result == cricket::SDR_BLOCK) break; } diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc index d9aa8512aa..8e916f1279 100644 --- a/webrtc/pc/channel.cc +++ b/webrtc/pc/channel.cc @@ -14,9 +14,9 @@ #include "webrtc/audio_sink.h" #include "webrtc/base/bind.h" -#include "webrtc/base/buffer.h" #include "webrtc/base/byteorder.h" #include "webrtc/base/common.h" +#include "webrtc/base/copyonwritebuffer.h" #include "webrtc/base/dscp.h" #include "webrtc/base/logging.h" #include "webrtc/base/trace_event.h" @@ -61,7 +61,7 @@ static void SafeSetError(const std::string& message, std::string* error_desc) { } struct PacketMessageData : public rtc::MessageData { - rtc::Buffer packet; + rtc::CopyOnWriteBuffer packet; rtc::PacketOptions options; }; @@ -93,7 +93,7 @@ static const char* PacketType(bool rtcp) { return (!rtcp) ? "RTP" : "RTCP"; } -static bool ValidPacket(bool rtcp, const rtc::Buffer* packet) { +static bool ValidPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { // Check the packet size. We could check the header too if needed. return (packet && packet->size() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) && @@ -435,12 +435,12 @@ bool BaseChannel::IsReadyToSend() const { (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp()); } -bool BaseChannel::SendPacket(rtc::Buffer* packet, +bool BaseChannel::SendPacket(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { return SendPacket(false, packet, options); } -bool BaseChannel::SendRtcp(rtc::Buffer* packet, +bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { return SendPacket(true, packet, options); } @@ -479,7 +479,7 @@ void BaseChannel::OnChannelRead(TransportChannel* channel, // When using RTCP multiplexing we might get RTCP packets on the RTP // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. bool rtcp = PacketIsRtcp(channel, data, len); - rtc::Buffer packet(data, len); + rtc::CopyOnWriteBuffer packet(data, len); HandlePacket(rtcp, &packet, packet_time); } @@ -529,7 +529,7 @@ bool BaseChannel::PacketIsRtcp(const TransportChannel* channel, } bool BaseChannel::SendPacket(bool rtcp, - rtc::Buffer* packet, + rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options) { // SendPacket gets called from MediaEngine, typically on an encoder thread. // If the thread is not our worker thread, we will post to our worker @@ -650,7 +650,7 @@ bool BaseChannel::SendPacket(bool rtcp, return true; } -bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { +bool BaseChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { // Protect ourselves against crazy data. if (!ValidPacket(rtcp, packet)) { LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " @@ -663,10 +663,10 @@ bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { return true; } // Check whether we handle this payload. - return bundle_filter_.DemuxPacket(packet->data(), packet->size()); + return bundle_filter_.DemuxPacket(packet->data(), packet->size()); } -void BaseChannel::HandlePacket(bool rtcp, rtc::Buffer* packet, +void BaseChannel::HandlePacket(bool rtcp, rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { if (!WantsPacket(rtcp, packet)) { return; @@ -1908,7 +1908,7 @@ bool DataChannel::Init() { } bool DataChannel::SendData(const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result) { return InvokeOnWorker(Bind(&DataMediaChannel::SendData, media_channel(), params, payload, result)); @@ -1919,7 +1919,7 @@ const ContentInfo* DataChannel::GetFirstContent( return GetFirstDataContent(sdesc); } -bool DataChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { +bool DataChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { if (data_channel_type_ == DCT_SCTP) { // TODO(pthatcher): Do this in a more robust way by checking for // SCTP or DTLS. diff --git a/webrtc/pc/channel.h b/webrtc/pc/channel.h index 1937b0483f..45657f88ee 100644 --- a/webrtc/pc/channel.h +++ b/webrtc/pc/channel.h @@ -191,10 +191,10 @@ class BaseChannel void FlushRtcpMessages(); // NetworkInterface implementation, called by MediaEngine - bool SendPacket(rtc::Buffer* packet, - const rtc::PacketOptions& options) override; - bool SendRtcp(rtc::Buffer* packet, const rtc::PacketOptions& options) - override; + bool SendPacket(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options) override; + bool SendRtcp(rtc::CopyOnWriteBuffer* packet, + const rtc::PacketOptions& options) override; // From TransportChannel void OnWritableState(TransportChannel* channel); @@ -210,10 +210,10 @@ class BaseChannel bool PacketIsRtcp(const TransportChannel* channel, const char* data, size_t len); bool SendPacket(bool rtcp, - rtc::Buffer* packet, + rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options); - virtual bool WantsPacket(bool rtcp, rtc::Buffer* packet); - void HandlePacket(bool rtcp, rtc::Buffer* packet, + virtual bool WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet); + void HandlePacket(bool rtcp, rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time); void EnableMedia_w(); @@ -502,7 +502,7 @@ class DataChannel : public BaseChannel { bool Init(); virtual bool SendData(const SendDataParams& params, - const rtc::Buffer& payload, + const rtc::CopyOnWriteBuffer& payload, SendDataResult* result); void StartMediaMonitor(int cms); @@ -516,8 +516,8 @@ class DataChannel : public BaseChannel { sigslot::signal2 SignalMediaMonitor; sigslot::signal2&> SignalConnectionMonitor; - sigslot::signal3 - SignalDataReceived; + sigslot::signal3 SignalDataReceived; // Signal for notifying when the channel becomes ready to send data. // That occurs when the channel is enabled, the transport is writable, // both local and remote descriptions are set, and the channel is unblocked. @@ -534,7 +534,7 @@ class DataChannel : public BaseChannel { private: struct SendDataMessageData : public rtc::MessageData { SendDataMessageData(const SendDataParams& params, - const rtc::Buffer* payload, + const rtc::CopyOnWriteBuffer* payload, SendDataResult* result) : params(params), payload(payload), @@ -543,7 +543,7 @@ class DataChannel : public BaseChannel { } const SendDataParams& params; - const rtc::Buffer* payload; + const rtc::CopyOnWriteBuffer* payload; SendDataResult* result; bool succeeded; }; @@ -558,7 +558,7 @@ class DataChannel : public BaseChannel { payload(data, len) { } const ReceiveDataParams params; - const rtc::Buffer payload; + const rtc::CopyOnWriteBuffer payload; }; typedef rtc::TypedMessageData DataChannelReadyToSendMessageData; @@ -581,7 +581,7 @@ class DataChannel : public BaseChannel { ContentAction action, std::string* error_desc); virtual void ChangeState(); - virtual bool WantsPacket(bool rtcp, rtc::Buffer* packet); + virtual bool WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet); virtual void OnMessage(rtc::Message* pmsg); virtual void GetSrtpCryptoSuites(std::vector* crypto_suites) const; diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc index 686f85d9ea..ecbdad4888 100644 --- a/webrtc/pc/channel_unittest.cc +++ b/webrtc/pc/channel_unittest.cc @@ -2769,7 +2769,7 @@ TEST_F(DataChannelTest, TestSendData) { unsigned char data[] = { 'f', 'o', 'o' }; - rtc::Buffer payload(data, 3); + rtc::CopyOnWriteBuffer payload(data, 3); cricket::SendDataResult result; ASSERT_TRUE(media_channel1_->SendData(params, payload, &result)); EXPECT_EQ(params.ssrc,