Update libjingle to 50191337.
R=mallinath@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1885005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4461 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
d3ae3c7b1f
commit
d64719d895
@ -34,7 +34,8 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
static size_t kMaxQueuedDataPackets = 100;
|
static size_t kMaxQueuedReceivedDataPackets = 100;
|
||||||
|
static size_t kMaxQueuedSendDataPackets = 100;
|
||||||
|
|
||||||
talk_base::scoped_refptr<DataChannel> DataChannel::Create(
|
talk_base::scoped_refptr<DataChannel> DataChannel::Create(
|
||||||
WebRtcSession* session,
|
WebRtcSession* session,
|
||||||
@ -95,12 +96,13 @@ bool DataChannel::HasNegotiationCompleted() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DataChannel::~DataChannel() {
|
DataChannel::~DataChannel() {
|
||||||
ClearQueuedData();
|
ClearQueuedReceivedData();
|
||||||
|
ClearQueuedSendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::RegisterObserver(DataChannelObserver* observer) {
|
void DataChannel::RegisterObserver(DataChannelObserver* observer) {
|
||||||
observer_ = observer;
|
observer_ = observer;
|
||||||
DeliverQueuedData();
|
DeliverQueuedReceivedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::UnregisterObserver() {
|
void DataChannel::UnregisterObserver() {
|
||||||
@ -117,7 +119,13 @@ bool DataChannel::reliable() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64 DataChannel::buffered_amount() const {
|
uint64 DataChannel::buffered_amount() const {
|
||||||
return 0;
|
uint64 buffered_amount = 0;
|
||||||
|
for (std::deque<DataBuffer*>::const_iterator it = queued_send_data_.begin();
|
||||||
|
it != queued_send_data_.end();
|
||||||
|
++it) {
|
||||||
|
buffered_amount += (*it)->size();
|
||||||
|
}
|
||||||
|
return buffered_amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::Close() {
|
void DataChannel::Close() {
|
||||||
@ -133,20 +141,22 @@ bool DataChannel::Send(const DataBuffer& buffer) {
|
|||||||
if (state_ != kOpen) {
|
if (state_ != kOpen) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cricket::SendDataParams send_params;
|
// If the queue is non-empty, we're waiting for SignalReadyToSend,
|
||||||
|
// so just add to the end of the queue and keep waiting.
|
||||||
send_params.ssrc = send_ssrc_;
|
if (!queued_send_data_.empty()) {
|
||||||
if (session_->data_channel_type() == cricket::DCT_SCTP) {
|
return QueueSendData(buffer);
|
||||||
send_params.ordered = config_.ordered;
|
|
||||||
send_params.max_rtx_count = config_.maxRetransmits;
|
|
||||||
send_params.max_rtx_ms = config_.maxRetransmitTime;
|
|
||||||
}
|
}
|
||||||
send_params.type = buffer.binary ? cricket::DMT_BINARY : cricket::DMT_TEXT;
|
|
||||||
|
|
||||||
cricket::SendDataResult send_result;
|
cricket::SendDataResult send_result;
|
||||||
// TODO(pthatcher): Use send_result.would_block for buffering.
|
if (!InternalSendWithoutQueueing(buffer, &send_result)) {
|
||||||
return session_->data_channel()->SendData(
|
if (send_result == cricket::SDR_BLOCK) {
|
||||||
send_params, buffer.data, &send_result);
|
return QueueSendData(buffer);
|
||||||
|
}
|
||||||
|
// Fail for other results.
|
||||||
|
// TODO(jiayl): We should close the data channel in this case.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::SetReceiveSsrc(uint32 receive_ssrc) {
|
void DataChannel::SetReceiveSsrc(uint32 receive_ssrc) {
|
||||||
@ -183,6 +193,43 @@ void DataChannel::OnDataEngineClose() {
|
|||||||
DoClose();
|
DoClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataChannel::OnDataReceived(cricket::DataChannel* channel,
|
||||||
|
const cricket::ReceiveDataParams& params,
|
||||||
|
const talk_base::Buffer& payload) {
|
||||||
|
if (params.ssrc != receive_ssrc_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool binary = (params.type == cricket::DMT_BINARY);
|
||||||
|
talk_base::scoped_ptr<DataBuffer> buffer(new DataBuffer(payload, binary));
|
||||||
|
if (was_ever_writable_ && observer_) {
|
||||||
|
observer_->OnMessage(*buffer.get());
|
||||||
|
} else {
|
||||||
|
if (queued_received_data_.size() > kMaxQueuedReceivedDataPackets) {
|
||||||
|
// TODO(jiayl): We should close the data channel in this case.
|
||||||
|
LOG(LS_ERROR)
|
||||||
|
<< "Queued received data exceeds the max number of packes.";
|
||||||
|
ClearQueuedReceivedData();
|
||||||
|
}
|
||||||
|
queued_received_data_.push(buffer.release());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataChannel::OnChannelReady(bool writable) {
|
||||||
|
if (!writable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Update the readyState if the channel is writable for the first time;
|
||||||
|
// otherwise it means the channel was blocked for sending and now unblocked,
|
||||||
|
// so send the queued data now.
|
||||||
|
if (!was_ever_writable_) {
|
||||||
|
was_ever_writable_ = true;
|
||||||
|
UpdateState();
|
||||||
|
} else if (state_ == kOpen) {
|
||||||
|
SendQueuedSendData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DataChannel::DoClose() {
|
void DataChannel::DoClose() {
|
||||||
receive_ssrc_set_ = false;
|
receive_ssrc_set_ = false;
|
||||||
send_ssrc_set_ = false;
|
send_ssrc_set_ = false;
|
||||||
@ -201,7 +248,7 @@ void DataChannel::UpdateState() {
|
|||||||
SetState(kOpen);
|
SetState(kOpen);
|
||||||
// If we have received buffers before the channel got writable.
|
// If we have received buffers before the channel got writable.
|
||||||
// Deliver them now.
|
// Deliver them now.
|
||||||
DeliverQueuedData();
|
DeliverQueuedReceivedData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -249,47 +296,76 @@ void DataChannel::DisconnectFromDataSession() {
|
|||||||
data_session_ = NULL;
|
data_session_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::DeliverQueuedData() {
|
void DataChannel::DeliverQueuedReceivedData() {
|
||||||
if (was_ever_writable_ && observer_) {
|
if (!was_ever_writable_ || !observer_) {
|
||||||
while (!queued_data_.empty()) {
|
return;
|
||||||
DataBuffer* buffer = queued_data_.front();
|
|
||||||
observer_->OnMessage(*buffer);
|
|
||||||
queued_data_.pop();
|
|
||||||
delete buffer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void DataChannel::ClearQueuedData() {
|
while (!queued_received_data_.empty()) {
|
||||||
while (!queued_data_.empty()) {
|
DataBuffer* buffer = queued_received_data_.front();
|
||||||
DataBuffer* buffer = queued_data_.front();
|
observer_->OnMessage(*buffer);
|
||||||
queued_data_.pop();
|
queued_received_data_.pop();
|
||||||
delete buffer;
|
delete buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::OnDataReceived(cricket::DataChannel* channel,
|
void DataChannel::ClearQueuedReceivedData() {
|
||||||
const cricket::ReceiveDataParams& params,
|
while (!queued_received_data_.empty()) {
|
||||||
const talk_base::Buffer& payload) {
|
DataBuffer* buffer = queued_received_data_.front();
|
||||||
if (params.ssrc == receive_ssrc_) {
|
queued_received_data_.pop();
|
||||||
bool binary = false;
|
delete buffer;
|
||||||
talk_base::scoped_ptr<DataBuffer> buffer(new DataBuffer(payload, binary));
|
|
||||||
if (was_ever_writable_ && observer_) {
|
|
||||||
observer_->OnMessage(*buffer.get());
|
|
||||||
} else {
|
|
||||||
if (queued_data_.size() > kMaxQueuedDataPackets) {
|
|
||||||
ClearQueuedData();
|
|
||||||
}
|
|
||||||
queued_data_.push(buffer.release());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataChannel::OnChannelReady(bool writable) {
|
void DataChannel::SendQueuedSendData() {
|
||||||
if (!was_ever_writable_ && writable) {
|
if (!was_ever_writable_) {
|
||||||
was_ever_writable_ = true;
|
return;
|
||||||
UpdateState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (!queued_send_data_.empty()) {
|
||||||
|
DataBuffer* buffer = queued_send_data_.front();
|
||||||
|
cricket::SendDataResult send_result;
|
||||||
|
if (!InternalSendWithoutQueueing(*buffer, &send_result)) {
|
||||||
|
LOG(LS_WARNING) << "SendQueuedSendData aborted due to send_result "
|
||||||
|
<< send_result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
queued_send_data_.pop_front();
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataChannel::ClearQueuedSendData() {
|
||||||
|
while (!queued_received_data_.empty()) {
|
||||||
|
DataBuffer* buffer = queued_received_data_.front();
|
||||||
|
queued_received_data_.pop();
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataChannel::InternalSendWithoutQueueing(
|
||||||
|
const DataBuffer& buffer, cricket::SendDataResult* send_result) {
|
||||||
|
cricket::SendDataParams send_params;
|
||||||
|
|
||||||
|
send_params.ssrc = send_ssrc_;
|
||||||
|
if (session_->data_channel_type() == cricket::DCT_SCTP) {
|
||||||
|
send_params.ordered = config_.ordered;
|
||||||
|
send_params.max_rtx_count = config_.maxRetransmits;
|
||||||
|
send_params.max_rtx_ms = config_.maxRetransmitTime;
|
||||||
|
}
|
||||||
|
send_params.type = buffer.binary ? cricket::DMT_BINARY : cricket::DMT_TEXT;
|
||||||
|
|
||||||
|
return session_->data_channel()->SendData(send_params, buffer.data,
|
||||||
|
send_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataChannel::QueueSendData(const DataBuffer& buffer) {
|
||||||
|
if (queued_send_data_.size() > kMaxQueuedSendDataPackets) {
|
||||||
|
LOG(LS_ERROR) << "Can't buffer any more data in the data channel.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
queued_send_data_.push_back(new DataBuffer(buffer));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -109,8 +109,13 @@ class DataChannel : public DataChannelInterface,
|
|||||||
void ConnectToDataSession();
|
void ConnectToDataSession();
|
||||||
void DisconnectFromDataSession();
|
void DisconnectFromDataSession();
|
||||||
bool IsConnectedToDataSession() { return data_session_ != NULL; }
|
bool IsConnectedToDataSession() { return data_session_ != NULL; }
|
||||||
void DeliverQueuedData();
|
void DeliverQueuedReceivedData();
|
||||||
void ClearQueuedData();
|
void ClearQueuedReceivedData();
|
||||||
|
void SendQueuedSendData();
|
||||||
|
void ClearQueuedSendData();
|
||||||
|
bool InternalSendWithoutQueueing(const DataBuffer& buffer,
|
||||||
|
cricket::SendDataResult* send_result);
|
||||||
|
bool QueueSendData(const DataBuffer& buffer);
|
||||||
|
|
||||||
std::string label_;
|
std::string label_;
|
||||||
DataChannelInit config_;
|
DataChannelInit config_;
|
||||||
@ -123,7 +128,8 @@ class DataChannel : public DataChannelInterface,
|
|||||||
uint32 send_ssrc_;
|
uint32 send_ssrc_;
|
||||||
bool receive_ssrc_set_;
|
bool receive_ssrc_set_;
|
||||||
uint32 receive_ssrc_;
|
uint32 receive_ssrc_;
|
||||||
std::queue<DataBuffer*> queued_data_;
|
std::queue<DataBuffer*> queued_received_data_;
|
||||||
|
std::deque<DataBuffer*> queued_send_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataChannelFactory {
|
class DataChannelFactory {
|
||||||
|
129
talk/app/webrtc/datachannel_unittest.cc
Normal file
129
talk/app/webrtc/datachannel_unittest.cc
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2013, Google Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "talk/app/webrtc/datachannel.h"
|
||||||
|
#include "talk/app/webrtc/mediastreamsignaling.h"
|
||||||
|
#include "talk/app/webrtc/test/fakeconstraints.h"
|
||||||
|
#include "talk/app/webrtc/webrtcsession.h"
|
||||||
|
#include "talk/base/gunit.h"
|
||||||
|
#include "talk/media/base/fakemediaengine.h"
|
||||||
|
#include "talk/media/devices/fakedevicemanager.h"
|
||||||
|
#include "talk/session/media/channelmanager.h"
|
||||||
|
|
||||||
|
using webrtc::MediaConstraintsInterface;
|
||||||
|
|
||||||
|
const uint32 kFakeSsrc = 1;
|
||||||
|
|
||||||
|
class SctpDataChannelTest : public testing::Test {
|
||||||
|
protected:
|
||||||
|
SctpDataChannelTest()
|
||||||
|
: media_engine_(new cricket::FakeMediaEngine),
|
||||||
|
data_engine_(new cricket::FakeDataEngine),
|
||||||
|
channel_manager_(
|
||||||
|
new cricket::ChannelManager(media_engine_,
|
||||||
|
data_engine_,
|
||||||
|
new cricket::FakeDeviceManager(),
|
||||||
|
new cricket::CaptureManager(),
|
||||||
|
talk_base::Thread::Current())),
|
||||||
|
session_(channel_manager_.get(),
|
||||||
|
talk_base::Thread::Current(),
|
||||||
|
talk_base::Thread::Current(),
|
||||||
|
NULL,
|
||||||
|
new webrtc::MediaStreamSignaling(talk_base::Thread::Current(),
|
||||||
|
NULL)),
|
||||||
|
webrtc_data_channel_(NULL) {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
if (!talk_base::SSLStreamAdapter::HaveDtlsSrtp()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channel_manager_->Init();
|
||||||
|
webrtc::FakeConstraints constraints;
|
||||||
|
constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, true);
|
||||||
|
constraints.AddMandatory(MediaConstraintsInterface::kEnableSctpDataChannels,
|
||||||
|
true);
|
||||||
|
ASSERT_TRUE(session_.Initialize(&constraints));
|
||||||
|
webrtc::SessionDescriptionInterface* offer = session_.CreateOffer(NULL);
|
||||||
|
ASSERT_TRUE(offer != NULL);
|
||||||
|
ASSERT_TRUE(session_.SetLocalDescription(offer, NULL));
|
||||||
|
|
||||||
|
webrtc_data_channel_ = webrtc::DataChannel::Create(&session_, "test", NULL);
|
||||||
|
// Connect to the media channel.
|
||||||
|
webrtc_data_channel_->SetSendSsrc(kFakeSsrc);
|
||||||
|
webrtc_data_channel_->SetReceiveSsrc(kFakeSsrc);
|
||||||
|
|
||||||
|
session_.data_channel()->SignalReadyToSendData(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSendBlocked(bool blocked) {
|
||||||
|
bool was_blocked = data_engine_->GetChannel(0)->is_send_blocked();
|
||||||
|
data_engine_->GetChannel(0)->set_send_blocked(blocked);
|
||||||
|
if (!blocked && was_blocked) {
|
||||||
|
session_.data_channel()->SignalReadyToSendData(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cricket::FakeMediaEngine* media_engine_;
|
||||||
|
cricket::FakeDataEngine* data_engine_;
|
||||||
|
talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
|
||||||
|
webrtc::WebRtcSession session_;
|
||||||
|
talk_base::scoped_refptr<webrtc::DataChannel> webrtc_data_channel_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tests that DataChannel::buffered_amount() is correct after the channel is
|
||||||
|
// blocked.
|
||||||
|
TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) {
|
||||||
|
if (!talk_base::SSLStreamAdapter::HaveDtlsSrtp()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
webrtc::DataBuffer buffer("abcd");
|
||||||
|
EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
|
||||||
|
|
||||||
|
EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
|
||||||
|
|
||||||
|
SetSendBlocked(true);
|
||||||
|
const int number_of_packets = 3;
|
||||||
|
for (int i = 0; i < number_of_packets; ++i) {
|
||||||
|
EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
|
||||||
|
}
|
||||||
|
EXPECT_EQ(buffer.data.length() * number_of_packets,
|
||||||
|
webrtc_data_channel_->buffered_amount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that the queued data are sent when the channel transitions from blocked
|
||||||
|
// to unblocked.
|
||||||
|
TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) {
|
||||||
|
if (!talk_base::SSLStreamAdapter::HaveDtlsSrtp()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
webrtc::DataBuffer buffer("abcd");
|
||||||
|
SetSendBlocked(true);
|
||||||
|
EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
|
||||||
|
|
||||||
|
SetSendBlocked(false);
|
||||||
|
EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
|
||||||
|
}
|
@ -75,6 +75,8 @@ struct DataBuffer {
|
|||||||
: data(text.data(), text.length()),
|
: data(text.data(), text.length()),
|
||||||
binary(false) {
|
binary(false) {
|
||||||
}
|
}
|
||||||
|
size_t size() const { return data.length(); }
|
||||||
|
|
||||||
talk_base::Buffer data;
|
talk_base::Buffer data;
|
||||||
// Indicates if the received data contains UTF-8 or binary 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.
|
// Note that the upper layers are left to verify the UTF-8 encoding.
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* libjingle
|
|
||||||
* Copyright 2004--2005, Google Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "talk/base/host.h"
|
|
||||||
|
|
||||||
#ifdef POSIX
|
|
||||||
#include <sys/utsname.h>
|
|
||||||
#endif // POSIX
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace talk_base {
|
|
||||||
|
|
||||||
std::string GetHostName() {
|
|
||||||
// TODO: fix or get rid of this
|
|
||||||
#if 0
|
|
||||||
struct utsname nm;
|
|
||||||
if (uname(&nm) < 0)
|
|
||||||
FatalError("uname", LAST_SYSTEM_ERROR);
|
|
||||||
return std::string(nm.nodename);
|
|
||||||
#endif
|
|
||||||
return "cricket";
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace talk_base
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* libjingle
|
|
||||||
* Copyright 2004--2005, Google Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TALK_BASE_HOST_H_
|
|
||||||
#define TALK_BASE_HOST_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace talk_base {
|
|
||||||
|
|
||||||
// Returns the name of the local host.
|
|
||||||
std::string GetHostName();
|
|
||||||
|
|
||||||
} // namespace talk_base
|
|
||||||
|
|
||||||
#endif // TALK_BASE_HOST_H_
|
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* libjingle
|
|
||||||
* Copyright 2004--2011, Google Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "talk/base/gunit.h"
|
|
||||||
#include "talk/base/host.h"
|
|
||||||
|
|
||||||
TEST(Host, GetHostName) {
|
|
||||||
EXPECT_NE("", talk_base::GetHostName());
|
|
||||||
}
|
|
@ -528,11 +528,14 @@ HttpRequestData::formatLeader(char* buffer, size_t size) const {
|
|||||||
|
|
||||||
HttpError
|
HttpError
|
||||||
HttpRequestData::parseLeader(const char* line, size_t len) {
|
HttpRequestData::parseLeader(const char* line, size_t len) {
|
||||||
UNUSED(len);
|
|
||||||
unsigned int vmajor, vminor;
|
unsigned int vmajor, vminor;
|
||||||
int vend, dstart, dend;
|
int vend, dstart, dend;
|
||||||
if ((sscanf(line, "%*s%n %n%*s%n HTTP/%u.%u", &vend, &dstart, &dend,
|
// sscanf isn't safe with strings that aren't null-terminated, and there is
|
||||||
&vmajor, &vminor) != 2)
|
// no guarantee that |line| is. Create a local copy that is null-terminated.
|
||||||
|
std::string line_str(line, len);
|
||||||
|
line = line_str.c_str();
|
||||||
|
if ((sscanf(line, "%*s%n %n%*s%n HTTP/%u.%u",
|
||||||
|
&vend, &dstart, &dend, &vmajor, &vminor) != 2)
|
||||||
|| (vmajor != 1)) {
|
|| (vmajor != 1)) {
|
||||||
return HE_PROTOCOL;
|
return HE_PROTOCOL;
|
||||||
}
|
}
|
||||||
@ -649,6 +652,10 @@ HttpResponseData::parseLeader(const char* line, size_t len) {
|
|||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
unsigned int vmajor, vminor, temp_scode;
|
unsigned int vmajor, vminor, temp_scode;
|
||||||
int temp_pos;
|
int temp_pos;
|
||||||
|
// sscanf isn't safe with strings that aren't null-terminated, and there is
|
||||||
|
// no guarantee that |line| is. Create a local copy that is null-terminated.
|
||||||
|
std::string line_str(line, len);
|
||||||
|
line = line_str.c_str();
|
||||||
if (sscanf(line, "HTTP %u%n",
|
if (sscanf(line, "HTTP %u%n",
|
||||||
&temp_scode, &temp_pos) == 1) {
|
&temp_scode, &temp_pos) == 1) {
|
||||||
// This server's response has no version. :( NOTE: This happens for every
|
// This server's response has no version. :( NOTE: This happens for every
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "talk/base/gunit.h"
|
#include "talk/base/gunit.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/natserver.h"
|
#include "talk/base/natserver.h"
|
||||||
#include "talk/base/natsocketfactory.h"
|
#include "talk/base/natsocketfactory.h"
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/scoped_ptr.h"
|
#include "talk/base/scoped_ptr.h"
|
||||||
#include "talk/base/socket.h" // includes something that makes windows happy
|
#include "talk/base/socket.h" // includes something that makes windows happy
|
||||||
@ -174,8 +173,7 @@ void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
BasicNetworkManager::BasicNetworkManager()
|
BasicNetworkManager::BasicNetworkManager()
|
||||||
: thread_(NULL),
|
: thread_(NULL), sent_first_update_(false), start_count_(0) {
|
||||||
start_count_(0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicNetworkManager::~BasicNetworkManager() {
|
BasicNetworkManager::~BasicNetworkManager() {
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "talk/base/gunit.h"
|
#include "talk/base/gunit.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/nethelpers.h"
|
#include "talk/base/nethelpers.h"
|
||||||
#include "talk/base/physicalsocketserver.h"
|
#include "talk/base/physicalsocketserver.h"
|
||||||
#include "talk/base/testclient.h"
|
#include "talk/base/testclient.h"
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "talk/base/asyncudpsocket.h"
|
#include "talk/base/asyncudpsocket.h"
|
||||||
#include "talk/base/event.h"
|
#include "talk/base/event.h"
|
||||||
#include "talk/base/gunit.h"
|
#include "talk/base/gunit.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/physicalsocketserver.h"
|
#include "talk/base/physicalsocketserver.h"
|
||||||
#include "talk/base/socketaddress.h"
|
#include "talk/base/socketaddress.h"
|
||||||
#include "talk/base/thread.h"
|
#include "talk/base/thread.h"
|
||||||
|
@ -300,8 +300,6 @@
|
|||||||
'base/gunit_prod.h',
|
'base/gunit_prod.h',
|
||||||
'base/helpers.cc',
|
'base/helpers.cc',
|
||||||
'base/helpers.h',
|
'base/helpers.h',
|
||||||
'base/host.cc',
|
|
||||||
'base/host.h',
|
|
||||||
'base/httpbase.cc',
|
'base/httpbase.cc',
|
||||||
'base/httpbase.h',
|
'base/httpbase.h',
|
||||||
'base/httpclient.cc',
|
'base/httpclient.cc',
|
||||||
|
@ -121,7 +121,6 @@
|
|||||||
'base/filelock_unittest.cc',
|
'base/filelock_unittest.cc',
|
||||||
'base/fileutils_unittest.cc',
|
'base/fileutils_unittest.cc',
|
||||||
'base/helpers_unittest.cc',
|
'base/helpers_unittest.cc',
|
||||||
'base/host_unittest.cc',
|
|
||||||
'base/httpbase_unittest.cc',
|
'base/httpbase_unittest.cc',
|
||||||
'base/httpcommon_unittest.cc',
|
'base/httpcommon_unittest.cc',
|
||||||
'base/httpserver_unittest.cc',
|
'base/httpserver_unittest.cc',
|
||||||
@ -376,6 +375,7 @@
|
|||||||
],
|
],
|
||||||
# TODO(ronghuawu): Reenable below unit tests that require gmock.
|
# TODO(ronghuawu): Reenable below unit tests that require gmock.
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'app/webrtc/datachannel_unittest.cc',
|
||||||
'app/webrtc/dtmfsender_unittest.cc',
|
'app/webrtc/dtmfsender_unittest.cc',
|
||||||
'app/webrtc/jsepsessiondescription_unittest.cc',
|
'app/webrtc/jsepsessiondescription_unittest.cc',
|
||||||
'app/webrtc/localaudiosource_unittest.cc',
|
'app/webrtc/localaudiosource_unittest.cc',
|
||||||
|
@ -145,12 +145,19 @@ int VideoCapturerState::DecCaptureStartRef() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CaptureManager::~CaptureManager() {
|
CaptureManager::~CaptureManager() {
|
||||||
while (!capture_states_.empty()) {
|
// Since we don't own any of the capturers, all capturers should have been
|
||||||
// There may have been multiple calls to StartVideoCapture which means that
|
// cleaned up before we get here. In fact, in the normal shutdown sequence,
|
||||||
// an equal number of calls to StopVideoCapture must be made. Note that
|
// all capturers *will* be shut down by now, so trying to stop them here
|
||||||
// StopVideoCapture will remove the element from |capture_states_| when a
|
// will crash. If we're still tracking any, it's a dangling pointer.
|
||||||
// successfull stop has been made.
|
if (!capture_states_.empty()) {
|
||||||
UnregisterVideoCapturer(capture_states_.begin()->second);
|
ASSERT(false &&
|
||||||
|
"CaptureManager destructing while still tracking capturers!");
|
||||||
|
// Delete remaining VideoCapturerStates, but don't touch the capturers.
|
||||||
|
do {
|
||||||
|
CaptureStates::iterator it = capture_states_.begin();
|
||||||
|
delete it->second;
|
||||||
|
capture_states_.erase(it);
|
||||||
|
} while (!capture_states_.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +180,10 @@ TEST_F(CaptureManagerTest, KeepFirstResolutionLow) {
|
|||||||
EXPECT_TRUE(video_capturer_.CaptureFrame());
|
EXPECT_TRUE(video_capturer_.CaptureFrame());
|
||||||
EXPECT_EQ(1, NumFramesRendered());
|
EXPECT_EQ(1, NumFramesRendered());
|
||||||
EXPECT_TRUE(WasRenderedResolution(format_qvga_));
|
EXPECT_TRUE(WasRenderedResolution(format_qvga_));
|
||||||
|
EXPECT_TRUE(capture_manager_.StopVideoCapture(&video_capturer_,
|
||||||
|
format_qvga_));
|
||||||
|
EXPECT_TRUE(capture_manager_.StopVideoCapture(&video_capturer_,
|
||||||
|
format_vga_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the reference counting is working when multiple start and
|
// Ensure that the reference counting is working when multiple start and
|
||||||
@ -230,6 +234,8 @@ TEST_F(CaptureManagerTest, TestForceRestart) {
|
|||||||
EXPECT_TRUE(video_capturer_.CaptureFrame());
|
EXPECT_TRUE(video_capturer_.CaptureFrame());
|
||||||
EXPECT_EQ(2, NumFramesRendered());
|
EXPECT_EQ(2, NumFramesRendered());
|
||||||
EXPECT_TRUE(WasRenderedResolution(format_vga_));
|
EXPECT_TRUE(WasRenderedResolution(format_vga_));
|
||||||
|
EXPECT_TRUE(capture_manager_.StopVideoCapture(&video_capturer_,
|
||||||
|
format_vga_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CaptureManagerTest, TestRequestRestart) {
|
TEST_F(CaptureManagerTest, TestRequestRestart) {
|
||||||
@ -248,4 +254,6 @@ TEST_F(CaptureManagerTest, TestRequestRestart) {
|
|||||||
EXPECT_TRUE(video_capturer_.CaptureFrame());
|
EXPECT_TRUE(video_capturer_.CaptureFrame());
|
||||||
EXPECT_EQ(2, NumFramesRendered());
|
EXPECT_EQ(2, NumFramesRendered());
|
||||||
EXPECT_TRUE(WasRenderedResolution(format_vga_));
|
EXPECT_TRUE(WasRenderedResolution(format_vga_));
|
||||||
|
EXPECT_TRUE(capture_manager_.StopVideoCapture(&video_capturer_,
|
||||||
|
format_qvga_));
|
||||||
}
|
}
|
||||||
|
@ -599,7 +599,7 @@ class FakeSoundclipMedia : public SoundclipMedia {
|
|||||||
class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
|
class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
|
||||||
public:
|
public:
|
||||||
explicit FakeDataMediaChannel(void* unused)
|
explicit FakeDataMediaChannel(void* unused)
|
||||||
: auto_bandwidth_(false), max_bps_(-1) {}
|
: auto_bandwidth_(false), send_blocked_(false), max_bps_(-1) {}
|
||||||
~FakeDataMediaChannel() {}
|
~FakeDataMediaChannel() {}
|
||||||
const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; }
|
const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; }
|
||||||
const std::vector<DataCodec>& send_codecs() const { return send_codecs_; }
|
const std::vector<DataCodec>& send_codecs() const { return send_codecs_; }
|
||||||
@ -647,13 +647,20 @@ class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
|
|||||||
virtual bool SendData(const SendDataParams& params,
|
virtual bool SendData(const SendDataParams& params,
|
||||||
const talk_base::Buffer& payload,
|
const talk_base::Buffer& payload,
|
||||||
SendDataResult* result) {
|
SendDataResult* result) {
|
||||||
last_sent_data_params_ = params;
|
if (send_blocked_) {
|
||||||
last_sent_data_ = std::string(payload.data(), payload.length());
|
*result = SDR_BLOCK;
|
||||||
return true;
|
return false;
|
||||||
|
} else {
|
||||||
|
last_sent_data_params_ = params;
|
||||||
|
last_sent_data_ = std::string(payload.data(), payload.length());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendDataParams last_sent_data_params() { return last_sent_data_params_; }
|
SendDataParams last_sent_data_params() { return last_sent_data_params_; }
|
||||||
std::string last_sent_data() { return last_sent_data_; }
|
std::string last_sent_data() { return last_sent_data_; }
|
||||||
|
bool is_send_blocked() { return send_blocked_; }
|
||||||
|
void set_send_blocked(bool blocked) { send_blocked_ = blocked; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<DataCodec> recv_codecs_;
|
std::vector<DataCodec> recv_codecs_;
|
||||||
@ -661,6 +668,7 @@ class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
|
|||||||
SendDataParams last_sent_data_params_;
|
SendDataParams last_sent_data_params_;
|
||||||
std::string last_sent_data_;
|
std::string last_sent_data_;
|
||||||
bool auto_bandwidth_;
|
bool auto_bandwidth_;
|
||||||
|
bool send_blocked_;
|
||||||
int max_bps_;
|
int max_bps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -957,6 +957,9 @@ class DataMediaChannel : public MediaChannel {
|
|||||||
// Signal errors from MediaChannel. Arguments are:
|
// Signal errors from MediaChannel. Arguments are:
|
||||||
// ssrc(uint32), and error(DataMediaChannel::Error).
|
// ssrc(uint32), and error(DataMediaChannel::Error).
|
||||||
sigslot::signal2<uint32, DataMediaChannel::Error> SignalMediaError;
|
sigslot::signal2<uint32, DataMediaChannel::Error> SignalMediaError;
|
||||||
|
// Signal when the media channel is ready to send the stream. Arguments are:
|
||||||
|
// writable(bool)
|
||||||
|
sigslot::signal1<bool> SignalReadyToSend;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
@ -270,7 +270,8 @@ bool SctpDataMediaChannel::OpenSctpSocket() {
|
|||||||
// Subscribe to SCTP event notifications.
|
// Subscribe to SCTP event notifications.
|
||||||
int event_types[] = {SCTP_ASSOC_CHANGE,
|
int event_types[] = {SCTP_ASSOC_CHANGE,
|
||||||
SCTP_PEER_ADDR_CHANGE,
|
SCTP_PEER_ADDR_CHANGE,
|
||||||
SCTP_SEND_FAILED_EVENT};
|
SCTP_SEND_FAILED_EVENT,
|
||||||
|
SCTP_SENDER_DRY_EVENT};
|
||||||
struct sctp_event event = {0};
|
struct sctp_event event = {0};
|
||||||
event.se_assoc_id = SCTP_ALL_ASSOC;
|
event.se_assoc_id = SCTP_ALL_ASSOC;
|
||||||
event.se_on = 1;
|
event.se_on = 1;
|
||||||
@ -479,11 +480,14 @@ bool SctpDataMediaChannel::SendData(
|
|||||||
static_cast<socklen_t>(sizeof(sndinfo)),
|
static_cast<socklen_t>(sizeof(sndinfo)),
|
||||||
SCTP_SENDV_SNDINFO, 0);
|
SCTP_SENDV_SNDINFO, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
LOG_ERRNO(LS_ERROR) << "ERROR:" << debug_name_
|
if (errno == EWOULDBLOCK) {
|
||||||
<< "SendData->(...): "
|
*result = SDR_BLOCK;
|
||||||
<< " usrsctp_sendv: ";
|
LOG(LS_INFO) << debug_name_ << "->SendData(...): EWOULDBLOCK returned";
|
||||||
// TODO(pthatcher): Make result SDR_BLOCK if the error is because
|
} else {
|
||||||
// it would block.
|
LOG_ERRNO(LS_ERROR) << "ERROR:" << debug_name_
|
||||||
|
<< "->SendData(...): "
|
||||||
|
<< " usrsctp_sendv: ";
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -562,8 +566,7 @@ void SctpDataMediaChannel::OnDataFromSctpToChannel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SctpDataMediaChannel::OnNotificationFromSctp(
|
void SctpDataMediaChannel::OnNotificationFromSctp(talk_base::Buffer* buffer) {
|
||||||
talk_base::Buffer* buffer) {
|
|
||||||
const sctp_notification& notification =
|
const sctp_notification& notification =
|
||||||
reinterpret_cast<const sctp_notification&>(*buffer->data());
|
reinterpret_cast<const sctp_notification&>(*buffer->data());
|
||||||
ASSERT(notification.sn_header.sn_length == buffer->length());
|
ASSERT(notification.sn_header.sn_length == buffer->length());
|
||||||
@ -591,6 +594,7 @@ void SctpDataMediaChannel::OnNotificationFromSctp(
|
|||||||
break;
|
break;
|
||||||
case SCTP_SENDER_DRY_EVENT:
|
case SCTP_SENDER_DRY_EVENT:
|
||||||
LOG(LS_INFO) << "SCTP_SENDER_DRY_EVENT";
|
LOG(LS_INFO) << "SCTP_SENDER_DRY_EVENT";
|
||||||
|
SignalReadyToSend(true);
|
||||||
break;
|
break;
|
||||||
// TODO(ldixon): Unblock after congestion.
|
// TODO(ldixon): Unblock after congestion.
|
||||||
case SCTP_NOTIFICATIONS_STOPPED_EVENT:
|
case SCTP_NOTIFICATIONS_STOPPED_EVENT:
|
||||||
|
@ -137,6 +137,24 @@ class SctpFakeDataReceiver : public sigslot::has_slots<> {
|
|||||||
cricket::ReceiveDataParams last_params_;
|
cricket::ReceiveDataParams last_params_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SignalReadyToSendObserver : public sigslot::has_slots<> {
|
||||||
|
public:
|
||||||
|
SignalReadyToSendObserver() : signaled_(false), writable_(false) {}
|
||||||
|
|
||||||
|
void OnSignaled(bool writable) {
|
||||||
|
signaled_ = true;
|
||||||
|
writable_ = writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSignaled(bool writable) {
|
||||||
|
return signaled_ && (writable_ == writable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool signaled_;
|
||||||
|
bool writable_;
|
||||||
|
};
|
||||||
|
|
||||||
// SCTP Data Engine testing framework.
|
// SCTP Data Engine testing framework.
|
||||||
class SctpDataMediaChannelTest : public testing::Test {
|
class SctpDataMediaChannelTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
@ -144,6 +162,42 @@ class SctpDataMediaChannelTest : public testing::Test {
|
|||||||
engine_.reset(new cricket::SctpDataEngine());
|
engine_.reset(new cricket::SctpDataEngine());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupConnectedChannels() {
|
||||||
|
net1_.reset(new SctpFakeNetworkInterface(talk_base::Thread::Current()));
|
||||||
|
net2_.reset(new SctpFakeNetworkInterface(talk_base::Thread::Current()));
|
||||||
|
recv1_.reset(new SctpFakeDataReceiver());
|
||||||
|
recv2_.reset(new SctpFakeDataReceiver());
|
||||||
|
chan1_.reset(CreateChannel(net1_.get(), recv1_.get()));
|
||||||
|
chan1_->set_debug_name("chan1/connector");
|
||||||
|
chan2_.reset(CreateChannel(net2_.get(), recv2_.get()));
|
||||||
|
chan2_->set_debug_name("chan2/listener");
|
||||||
|
// Setup two connected channels ready to send and receive.
|
||||||
|
net1_->SetDestination(chan2_.get());
|
||||||
|
net2_->SetDestination(chan1_.get());
|
||||||
|
|
||||||
|
LOG(LS_VERBOSE) << "Channel setup ----------------------------- ";
|
||||||
|
chan1_->AddSendStream(cricket::StreamParams::CreateLegacy(1));
|
||||||
|
chan2_->AddRecvStream(cricket::StreamParams::CreateLegacy(1));
|
||||||
|
|
||||||
|
chan2_->AddSendStream(cricket::StreamParams::CreateLegacy(2));
|
||||||
|
chan1_->AddRecvStream(cricket::StreamParams::CreateLegacy(2));
|
||||||
|
|
||||||
|
LOG(LS_VERBOSE) << "Connect the channels -----------------------------";
|
||||||
|
// chan1 wants to setup a data connection.
|
||||||
|
chan1_->SetReceive(true);
|
||||||
|
// chan1 will have sent chan2 a request to setup a data connection. After
|
||||||
|
// chan2 accepts the offer, chan2 connects to chan1 with the following.
|
||||||
|
chan2_->SetReceive(true);
|
||||||
|
chan2_->SetSend(true);
|
||||||
|
// Makes sure that network packets are delivered and simulates a
|
||||||
|
// deterministic and realistic small timing delay between the SetSend calls.
|
||||||
|
ProcessMessagesUntilIdle();
|
||||||
|
|
||||||
|
// chan1 and chan2 are now connected so chan1 enables sending to complete
|
||||||
|
// the creation of the connection.
|
||||||
|
chan1_->SetSend(true);
|
||||||
|
}
|
||||||
|
|
||||||
cricket::SctpDataMediaChannel* CreateChannel(
|
cricket::SctpDataMediaChannel* CreateChannel(
|
||||||
SctpFakeNetworkInterface* net, SctpFakeDataReceiver* recv) {
|
SctpFakeNetworkInterface* net, SctpFakeDataReceiver* recv) {
|
||||||
cricket::SctpDataMediaChannel* channel =
|
cricket::SctpDataMediaChannel* channel =
|
||||||
@ -182,79 +236,78 @@ class SctpDataMediaChannelTest : public testing::Test {
|
|||||||
return !thread->IsQuitting();
|
return !thread->IsQuitting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cricket::SctpDataMediaChannel* channel1() { return chan1_.get(); }
|
||||||
|
cricket::SctpDataMediaChannel* channel2() { return chan2_.get(); }
|
||||||
|
SctpFakeDataReceiver* receiver1() { return recv1_.get(); }
|
||||||
|
SctpFakeDataReceiver* receiver2() { return recv2_.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
talk_base::scoped_ptr<cricket::SctpDataEngine> engine_;
|
talk_base::scoped_ptr<cricket::SctpDataEngine> engine_;
|
||||||
|
talk_base::scoped_ptr<SctpFakeNetworkInterface> net1_;
|
||||||
|
talk_base::scoped_ptr<SctpFakeNetworkInterface> net2_;
|
||||||
|
talk_base::scoped_ptr<SctpFakeDataReceiver> recv1_;
|
||||||
|
talk_base::scoped_ptr<SctpFakeDataReceiver> recv2_;
|
||||||
|
talk_base::scoped_ptr<cricket::SctpDataMediaChannel> chan1_;
|
||||||
|
talk_base::scoped_ptr<cricket::SctpDataMediaChannel> chan2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Verifies that SignalReadyToSend is fired.
|
||||||
|
TEST_F(SctpDataMediaChannelTest, SignalReadyToSend) {
|
||||||
|
SetupConnectedChannels();
|
||||||
|
|
||||||
|
SignalReadyToSendObserver signal_observer_1;
|
||||||
|
SignalReadyToSendObserver signal_observer_2;
|
||||||
|
|
||||||
|
channel1()->SignalReadyToSend.connect(&signal_observer_1,
|
||||||
|
&SignalReadyToSendObserver::OnSignaled);
|
||||||
|
channel2()->SignalReadyToSend.connect(&signal_observer_2,
|
||||||
|
&SignalReadyToSendObserver::OnSignaled);
|
||||||
|
|
||||||
|
cricket::SendDataResult result;
|
||||||
|
ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result));
|
||||||
|
EXPECT_EQ(cricket::SDR_SUCCESS, result);
|
||||||
|
EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000);
|
||||||
|
ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result));
|
||||||
|
EXPECT_EQ(cricket::SDR_SUCCESS, result);
|
||||||
|
EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000);
|
||||||
|
|
||||||
|
EXPECT_TRUE_WAIT(signal_observer_1.IsSignaled(true), 1000);
|
||||||
|
EXPECT_TRUE_WAIT(signal_observer_2.IsSignaled(true), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SctpDataMediaChannelTest, SendData) {
|
TEST_F(SctpDataMediaChannelTest, SendData) {
|
||||||
talk_base::scoped_ptr<SctpFakeNetworkInterface> net1(
|
SetupConnectedChannels();
|
||||||
new SctpFakeNetworkInterface(talk_base::Thread::Current()));
|
|
||||||
talk_base::scoped_ptr<SctpFakeNetworkInterface> net2(
|
|
||||||
new SctpFakeNetworkInterface(talk_base::Thread::Current()));
|
|
||||||
talk_base::scoped_ptr<SctpFakeDataReceiver> recv1(
|
|
||||||
new SctpFakeDataReceiver());
|
|
||||||
talk_base::scoped_ptr<SctpFakeDataReceiver> recv2(
|
|
||||||
new SctpFakeDataReceiver());
|
|
||||||
talk_base::scoped_ptr<cricket::SctpDataMediaChannel> chan1(
|
|
||||||
CreateChannel(net1.get(), recv1.get()));
|
|
||||||
chan1->set_debug_name("chan1/connector");
|
|
||||||
talk_base::scoped_ptr<cricket::SctpDataMediaChannel> chan2(
|
|
||||||
CreateChannel(net2.get(), recv2.get()));
|
|
||||||
chan2->set_debug_name("chan2/listener");
|
|
||||||
|
|
||||||
net1->SetDestination(chan2.get());
|
|
||||||
net2->SetDestination(chan1.get());
|
|
||||||
|
|
||||||
LOG(LS_VERBOSE) << "Channel setup ----------------------------- ";
|
|
||||||
chan1->AddSendStream(cricket::StreamParams::CreateLegacy(1));
|
|
||||||
chan2->AddRecvStream(cricket::StreamParams::CreateLegacy(1));
|
|
||||||
|
|
||||||
chan2->AddSendStream(cricket::StreamParams::CreateLegacy(2));
|
|
||||||
chan1->AddRecvStream(cricket::StreamParams::CreateLegacy(2));
|
|
||||||
|
|
||||||
LOG(LS_VERBOSE) << "Connect the channels -----------------------------";
|
|
||||||
// chan1 wants to setup a data connection.
|
|
||||||
chan1->SetReceive(true);
|
|
||||||
// chan1 will have sent chan2 a request to setup a data connection. After
|
|
||||||
// chan2 accepts the offer, chan2 connects to chan1 with the following.
|
|
||||||
chan2->SetReceive(true);
|
|
||||||
chan2->SetSend(true);
|
|
||||||
// Makes sure that network packets are delivered and simulates a
|
|
||||||
// deterministic and realistic small timing delay between the SetSend calls.
|
|
||||||
ProcessMessagesUntilIdle();
|
|
||||||
|
|
||||||
// chan1 and chan2 are now connected so chan1 enables sending to complete
|
|
||||||
// the creation of the connection.
|
|
||||||
chan1->SetSend(true);
|
|
||||||
|
|
||||||
cricket::SendDataResult result;
|
cricket::SendDataResult result;
|
||||||
LOG(LS_VERBOSE) << "chan1 sending: 'hello?' -----------------------------";
|
LOG(LS_VERBOSE) << "chan1 sending: 'hello?' -----------------------------";
|
||||||
ASSERT_TRUE(SendData(chan1.get(), 1, "hello?", &result));
|
ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result));
|
||||||
EXPECT_EQ(cricket::SDR_SUCCESS, result);
|
EXPECT_EQ(cricket::SDR_SUCCESS, result);
|
||||||
EXPECT_TRUE_WAIT(ReceivedData(recv2.get(), 1, "hello?"), 1000);
|
EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000);
|
||||||
LOG(LS_VERBOSE) << "recv2.received=" << recv2->received()
|
LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received()
|
||||||
<< "recv2.last_params.ssrc=" << recv2->last_params().ssrc
|
<< "recv2.last_params.ssrc="
|
||||||
|
<< receiver2()->last_params().ssrc
|
||||||
<< "recv2.last_params.timestamp="
|
<< "recv2.last_params.timestamp="
|
||||||
<< recv2->last_params().ssrc
|
<< receiver2()->last_params().ssrc
|
||||||
<< "recv2.last_params.seq_num="
|
<< "recv2.last_params.seq_num="
|
||||||
<< recv2->last_params().seq_num
|
<< receiver2()->last_params().seq_num
|
||||||
<< "recv2.last_data=" << recv2->last_data();
|
<< "recv2.last_data=" << receiver2()->last_data();
|
||||||
|
|
||||||
LOG(LS_VERBOSE) << "chan2 sending: 'hi chan1' -----------------------------";
|
LOG(LS_VERBOSE) << "chan2 sending: 'hi chan1' -----------------------------";
|
||||||
ASSERT_TRUE(SendData(chan2.get(), 2, "hi chan1", &result));
|
ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result));
|
||||||
EXPECT_EQ(cricket::SDR_SUCCESS, result);
|
EXPECT_EQ(cricket::SDR_SUCCESS, result);
|
||||||
EXPECT_TRUE_WAIT(ReceivedData(recv1.get(), 2, "hi chan1"), 1000);
|
EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000);
|
||||||
LOG(LS_VERBOSE) << "recv1.received=" << recv1->received()
|
LOG(LS_VERBOSE) << "recv1.received=" << receiver1()->received()
|
||||||
<< "recv1.last_params.ssrc=" << recv1->last_params().ssrc
|
<< "recv1.last_params.ssrc="
|
||||||
|
<< receiver1()->last_params().ssrc
|
||||||
<< "recv1.last_params.timestamp="
|
<< "recv1.last_params.timestamp="
|
||||||
<< recv1->last_params().ssrc
|
<< receiver1()->last_params().ssrc
|
||||||
<< "recv1.last_params.seq_num="
|
<< "recv1.last_params.seq_num="
|
||||||
<< recv1->last_params().seq_num
|
<< receiver1()->last_params().seq_num
|
||||||
<< "recv1.last_data=" << recv1->last_data();
|
<< "recv1.last_data=" << receiver1()->last_data();
|
||||||
|
|
||||||
LOG(LS_VERBOSE) << "Closing down. -----------------------------";
|
LOG(LS_VERBOSE) << "Closing down. -----------------------------";
|
||||||
// Disconnects and closes socket, including setting receiving to false.
|
// Disconnects and closes socket, including setting receiving to false.
|
||||||
chan1->SetSend(false);
|
channel1()->SetSend(false);
|
||||||
chan2->SetSend(false);
|
channel2()->SetSend(false);
|
||||||
LOG(LS_VERBOSE) << "Cleaning up. -----------------------------";
|
LOG(LS_VERBOSE) << "Cleaning up. -----------------------------";
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,7 @@ class WebRtcVideoChannelRecvInfo {
|
|||||||
DecoderMap registered_decoders_;
|
DecoderMap registered_decoders_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebRtcVideoChannelSendInfo {
|
class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
|
||||||
public:
|
public:
|
||||||
typedef std::map<int, webrtc::VideoEncoder*> EncoderMap; // key: payload type
|
typedef std::map<int, webrtc::VideoEncoder*> EncoderMap; // key: payload type
|
||||||
WebRtcVideoChannelSendInfo(int channel_id, int capture_id,
|
WebRtcVideoChannelSendInfo(int channel_id, int capture_id,
|
||||||
@ -445,9 +445,7 @@ class WebRtcVideoChannelSendInfo {
|
|||||||
capturer_updated_(false),
|
capturer_updated_(false),
|
||||||
interval_(0),
|
interval_(0),
|
||||||
video_adapter_(new CoordinatedVideoAdapter) {
|
video_adapter_(new CoordinatedVideoAdapter) {
|
||||||
// TODO(asapersson):
|
SignalCpuAdaptationUnable.repeat(video_adapter_->SignalCpuAdaptationUnable);
|
||||||
// video_adapter_->SignalCpuAdaptationUnable.connect(
|
|
||||||
// this, &WebRtcVideoChannelSendInfo::OnCpuAdaptationUnable);
|
|
||||||
if (cpu_monitor) {
|
if (cpu_monitor) {
|
||||||
cpu_monitor->SignalUpdate.connect(
|
cpu_monitor->SignalUpdate.connect(
|
||||||
video_adapter_.get(), &CoordinatedVideoAdapter::OnCpuLoadUpdated);
|
video_adapter_.get(), &CoordinatedVideoAdapter::OnCpuLoadUpdated);
|
||||||
@ -585,6 +583,8 @@ class WebRtcVideoChannelSendInfo {
|
|||||||
registered_encoders_.clear();
|
registered_encoders_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigslot::repeater0<> SignalCpuAdaptationUnable;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int channel_id_;
|
int channel_id_;
|
||||||
int capture_id_;
|
int capture_id_;
|
||||||
@ -2931,6 +2931,8 @@ bool WebRtcVideoMediaChannel::ConfigureSending(int channel_id,
|
|||||||
external_capture,
|
external_capture,
|
||||||
engine()->cpu_monitor()));
|
engine()->cpu_monitor()));
|
||||||
send_channel->ApplyCpuOptions(options_);
|
send_channel->ApplyCpuOptions(options_);
|
||||||
|
send_channel->SignalCpuAdaptationUnable.connect(this,
|
||||||
|
&WebRtcVideoMediaChannel::OnCpuAdaptationUnable);
|
||||||
|
|
||||||
// Register encoder observer for outgoing framerate and bitrate.
|
// Register encoder observer for outgoing framerate and bitrate.
|
||||||
if (engine()->vie()->codec()->RegisterEncoderObserver(
|
if (engine()->vie()->codec()->RegisterEncoderObserver(
|
||||||
@ -3404,6 +3406,12 @@ void WebRtcVideoMediaChannel::FlushBlackFrame(uint32 ssrc, int64 timestamp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebRtcVideoMediaChannel::OnCpuAdaptationUnable() {
|
||||||
|
// ssrc is hardcoded to 0. This message is based on a system wide issue,
|
||||||
|
// so finding which ssrc caused it doesn't matter.
|
||||||
|
SignalMediaError(0, VideoMediaChannel::ERROR_REC_CPU_MAX_CANT_DOWNGRADE);
|
||||||
|
}
|
||||||
|
|
||||||
void WebRtcVideoMediaChannel::SetNetworkTransmissionState(
|
void WebRtcVideoMediaChannel::SetNetworkTransmissionState(
|
||||||
bool is_transmitting) {
|
bool is_transmitting) {
|
||||||
LOG(LS_INFO) << "SetNetworkTransmissionState: " << is_transmitting;
|
LOG(LS_INFO) << "SetNetworkTransmissionState: " << is_transmitting;
|
||||||
|
@ -396,6 +396,9 @@ class WebRtcVideoMediaChannel : public talk_base::MessageHandler,
|
|||||||
const std::vector<RtpHeaderExtension>& extensions,
|
const std::vector<RtpHeaderExtension>& extensions,
|
||||||
const char header_extension_uri[]);
|
const char header_extension_uri[]);
|
||||||
|
|
||||||
|
// Signal when cpu adaptation has no further scope to adapt.
|
||||||
|
void OnCpuAdaptationUnable();
|
||||||
|
|
||||||
// Global state.
|
// Global state.
|
||||||
WebRtcVideoEngine* engine_;
|
WebRtcVideoEngine* engine_;
|
||||||
VoiceMediaChannel* voice_channel_;
|
VoiceMediaChannel* voice_channel_;
|
||||||
|
@ -86,7 +86,9 @@ class FakeViEWrapper : public cricket::ViEWrapper {
|
|||||||
|
|
||||||
// Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine.
|
// Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine.
|
||||||
// Useful for testing failure paths.
|
// Useful for testing failure paths.
|
||||||
class WebRtcVideoEngineTestFake : public testing::Test {
|
class WebRtcVideoEngineTestFake :
|
||||||
|
public testing::Test,
|
||||||
|
public sigslot::has_slots<> {
|
||||||
public:
|
public:
|
||||||
WebRtcVideoEngineTestFake()
|
WebRtcVideoEngineTestFake()
|
||||||
: vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
|
: vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
|
||||||
@ -95,16 +97,22 @@ class WebRtcVideoEngineTestFake : public testing::Test {
|
|||||||
engine_(NULL, // cricket::WebRtcVoiceEngine
|
engine_(NULL, // cricket::WebRtcVoiceEngine
|
||||||
new FakeViEWrapper(&vie_), cpu_monitor_),
|
new FakeViEWrapper(&vie_), cpu_monitor_),
|
||||||
channel_(NULL),
|
channel_(NULL),
|
||||||
voice_channel_(NULL) {
|
voice_channel_(NULL),
|
||||||
|
last_error_(cricket::VideoMediaChannel::ERROR_NONE) {
|
||||||
}
|
}
|
||||||
bool SetupEngine() {
|
bool SetupEngine() {
|
||||||
bool result = engine_.Init(talk_base::Thread::Current());
|
bool result = engine_.Init(talk_base::Thread::Current());
|
||||||
if (result) {
|
if (result) {
|
||||||
channel_ = engine_.CreateChannel(voice_channel_);
|
channel_ = engine_.CreateChannel(voice_channel_);
|
||||||
|
channel_->SignalMediaError.connect(this,
|
||||||
|
&WebRtcVideoEngineTestFake::OnMediaError);
|
||||||
result = (channel_ != NULL);
|
result = (channel_ != NULL);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
void OnMediaError(uint32 ssrc, cricket::VideoMediaChannel::Error error) {
|
||||||
|
last_error_ = error;
|
||||||
|
}
|
||||||
bool SendI420Frame(int width, int height) {
|
bool SendI420Frame(int width, int height) {
|
||||||
if (NULL == channel_) {
|
if (NULL == channel_) {
|
||||||
return false;
|
return false;
|
||||||
@ -185,6 +193,7 @@ class WebRtcVideoEngineTestFake : public testing::Test {
|
|||||||
cricket::WebRtcVideoEngine engine_;
|
cricket::WebRtcVideoEngine engine_;
|
||||||
cricket::WebRtcVideoMediaChannel* channel_;
|
cricket::WebRtcVideoMediaChannel* channel_;
|
||||||
cricket::WebRtcVoiceMediaChannel* voice_channel_;
|
cricket::WebRtcVoiceMediaChannel* voice_channel_;
|
||||||
|
cricket::VideoMediaChannel::Error last_error_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine.
|
// Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine.
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "talk/base/crc32.h"
|
#include "talk/base/crc32.h"
|
||||||
#include "talk/base/gunit.h"
|
#include "talk/base/gunit.h"
|
||||||
#include "talk/base/helpers.h"
|
#include "talk/base/helpers.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/natserver.h"
|
#include "talk/base/natserver.h"
|
||||||
#include "talk/base/natsocketfactory.h"
|
#include "talk/base/natsocketfactory.h"
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "talk/base/gunit.h"
|
#include "talk/base/gunit.h"
|
||||||
#include "talk/base/helpers.h"
|
#include "talk/base/helpers.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/physicalsocketserver.h"
|
#include "talk/base/physicalsocketserver.h"
|
||||||
#include "talk/base/socketaddress.h"
|
#include "talk/base/socketaddress.h"
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "talk/base/common.h"
|
#include "talk/base/common.h"
|
||||||
#include "talk/base/gunit.h"
|
#include "talk/base/gunit.h"
|
||||||
#include "talk/base/helpers.h"
|
#include "talk/base/helpers.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/base/natserver.h"
|
#include "talk/base/natserver.h"
|
||||||
#include "talk/base/natsocketfactory.h"
|
#include "talk/base/natsocketfactory.h"
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/thread.h"
|
#include "talk/base/thread.h"
|
||||||
#include "talk/p2p/base/stunserver.h"
|
#include "talk/p2p/base/stunserver.h"
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#include "talk/base/common.h"
|
#include "talk/base/common.h"
|
||||||
#include "talk/base/helpers.h"
|
#include "talk/base/helpers.h"
|
||||||
#include "talk/base/host.h"
|
|
||||||
#include "talk/base/logging.h"
|
#include "talk/base/logging.h"
|
||||||
#include "talk/p2p/base/basicpacketsocketfactory.h"
|
#include "talk/p2p/base/basicpacketsocketfactory.h"
|
||||||
#include "talk/p2p/base/common.h"
|
#include "talk/p2p/base/common.h"
|
||||||
|
@ -2294,6 +2294,7 @@ void VideoChannel::OnMessage(talk_base::Message *pmsg) {
|
|||||||
SetScreenCaptureFactoryMessageData* data =
|
SetScreenCaptureFactoryMessageData* data =
|
||||||
static_cast<SetScreenCaptureFactoryMessageData*>(pmsg->pdata);
|
static_cast<SetScreenCaptureFactoryMessageData*>(pmsg->pdata);
|
||||||
SetScreenCaptureFactory_w(data->screencapture_factory);
|
SetScreenCaptureFactory_w(data->screencapture_factory);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case MSG_GETSTATS: {
|
case MSG_GETSTATS: {
|
||||||
VideoStatsMessageData* data =
|
VideoStatsMessageData* data =
|
||||||
@ -2428,6 +2429,8 @@ bool DataChannel::Init() {
|
|||||||
this, &DataChannel::OnDataReceived);
|
this, &DataChannel::OnDataReceived);
|
||||||
media_channel()->SignalMediaError.connect(
|
media_channel()->SignalMediaError.connect(
|
||||||
this, &DataChannel::OnDataChannelError);
|
this, &DataChannel::OnDataChannelError);
|
||||||
|
media_channel()->SignalReadyToSend.connect(
|
||||||
|
this, &DataChannel::OnDataChannelReadyToSend);
|
||||||
srtp_filter()->SignalSrtpError.connect(
|
srtp_filter()->SignalSrtpError.connect(
|
||||||
this, &DataChannel::OnSrtpError);
|
this, &DataChannel::OnSrtpError);
|
||||||
return true;
|
return true;
|
||||||
@ -2609,7 +2612,7 @@ void DataChannel::ChangeState() {
|
|||||||
|
|
||||||
// Post to trigger SignalReadyToSendData.
|
// Post to trigger SignalReadyToSendData.
|
||||||
signaling_thread()->Post(this, MSG_READYTOSENDDATA,
|
signaling_thread()->Post(this, MSG_READYTOSENDDATA,
|
||||||
new BoolMessageData(send));
|
new DataChannelReadyToSendMessageData(send));
|
||||||
|
|
||||||
LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
|
LOG(LS_INFO) << "Changing data state, recv=" << recv << " send=" << send;
|
||||||
}
|
}
|
||||||
@ -2617,7 +2620,8 @@ void DataChannel::ChangeState() {
|
|||||||
void DataChannel::OnMessage(talk_base::Message *pmsg) {
|
void DataChannel::OnMessage(talk_base::Message *pmsg) {
|
||||||
switch (pmsg->message_id) {
|
switch (pmsg->message_id) {
|
||||||
case MSG_READYTOSENDDATA: {
|
case MSG_READYTOSENDDATA: {
|
||||||
BoolMessageData* data = static_cast<BoolMessageData*>(pmsg->pdata);
|
DataChannelReadyToSendMessageData* data =
|
||||||
|
static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
|
||||||
SignalReadyToSendData(data->data());
|
SignalReadyToSendData(data->data());
|
||||||
delete data;
|
delete data;
|
||||||
break;
|
break;
|
||||||
@ -2690,6 +2694,14 @@ void DataChannel::OnDataChannelError(
|
|||||||
signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
|
signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataChannel::OnDataChannelReadyToSend(bool writable) {
|
||||||
|
// This is usded for congestion control to indicate that the stream is ready
|
||||||
|
// to send by the MediaChannel, as opposed to OnReadyToSend, which indicates
|
||||||
|
// that the transport channel is ready.
|
||||||
|
signaling_thread()->Post(this, MSG_READYTOSENDDATA,
|
||||||
|
new DataChannelReadyToSendMessageData(writable));
|
||||||
|
}
|
||||||
|
|
||||||
void DataChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
|
void DataChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
|
||||||
SrtpFilter::Error error) {
|
SrtpFilter::Error error) {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
|
@ -595,9 +595,9 @@ class DataChannel : public BaseChannel {
|
|||||||
return static_cast<DataMediaChannel*>(BaseChannel::media_channel());
|
return static_cast<DataMediaChannel*>(BaseChannel::media_channel());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendData(const SendDataParams& params,
|
virtual bool SendData(const SendDataParams& params,
|
||||||
const talk_base::Buffer& payload,
|
const talk_base::Buffer& payload,
|
||||||
SendDataResult* result);
|
SendDataResult* result);
|
||||||
|
|
||||||
void StartMediaMonitor(int cms);
|
void StartMediaMonitor(int cms);
|
||||||
void StopMediaMonitor();
|
void StopMediaMonitor();
|
||||||
@ -612,9 +612,8 @@ class DataChannel : public BaseChannel {
|
|||||||
const talk_base::Buffer&>
|
const talk_base::Buffer&>
|
||||||
SignalDataReceived;
|
SignalDataReceived;
|
||||||
// Signal for notifying when the channel becomes ready to send data.
|
// Signal for notifying when the channel becomes ready to send data.
|
||||||
// That occurs when the channel is enabled, the transport is writable and
|
// That occurs when the channel is enabled, the transport is writable,
|
||||||
// both local and remote descriptions are set.
|
// both local and remote descriptions are set, and the channel is unblocked.
|
||||||
// TODO(perkj): Signal this per SSRC stream.
|
|
||||||
sigslot::signal1<bool> SignalReadyToSendData;
|
sigslot::signal1<bool> SignalReadyToSendData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -647,6 +646,8 @@ class DataChannel : public BaseChannel {
|
|||||||
const talk_base::Buffer payload;
|
const talk_base::Buffer payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef talk_base::TypedMessageData<bool> DataChannelReadyToSendMessageData;
|
||||||
|
|
||||||
// overrides from BaseChannel
|
// overrides from BaseChannel
|
||||||
virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
|
virtual const ContentInfo* GetFirstContent(const SessionDescription* sdesc);
|
||||||
// If data_channel_type_ is DCT_NONE, set it. Otherwise, check that
|
// If data_channel_type_ is DCT_NONE, set it. Otherwise, check that
|
||||||
@ -674,6 +675,7 @@ class DataChannel : public BaseChannel {
|
|||||||
void OnDataReceived(
|
void OnDataReceived(
|
||||||
const ReceiveDataParams& params, const char* data, size_t len);
|
const ReceiveDataParams& params, const char* data, size_t len);
|
||||||
void OnDataChannelError(uint32 ssrc, DataMediaChannel::Error error);
|
void OnDataChannelError(uint32 ssrc, DataMediaChannel::Error error);
|
||||||
|
void OnDataChannelReadyToSend(bool writable);
|
||||||
void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
|
void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
|
||||||
|
|
||||||
talk_base::scoped_ptr<DataMediaMonitor> media_monitor_;
|
talk_base::scoped_ptr<DataMediaMonitor> media_monitor_;
|
||||||
|
@ -297,8 +297,6 @@ class ChannelManager : public talk_base::MessageHandler,
|
|||||||
bool capturing_;
|
bool capturing_;
|
||||||
bool monitoring_;
|
bool monitoring_;
|
||||||
|
|
||||||
talk_base::scoped_ptr<VideoCapturer> video_capturer_;
|
|
||||||
|
|
||||||
// String containing currently set device. Note that this string is subtly
|
// String containing currently set device. Note that this string is subtly
|
||||||
// different from camera_device_. E.g. camera_device_ will list unplugged
|
// different from camera_device_. E.g. camera_device_ will list unplugged
|
||||||
// but selected devices while this sting will be empty or contain current
|
// but selected devices while this sting will be empty or contain current
|
||||||
|
Loading…
x
Reference in New Issue
Block a user