Update talk to 50918584.
Together with Stefan's http://review.webrtc.org/1960004/. R=mallinath@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2048004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4556 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -87,8 +87,6 @@ enum ViEErrors {
|
||||
kViENetworkSendCodecNotSet, // SetSendGQoS- Need to set the send codec first.
|
||||
kViENetworkServiceTypeNotSupported, // SetSendGQoS
|
||||
kViENetworkNotSupported, // SetSendGQoS Not supported on this OS.
|
||||
kViENetworkObserverAlreadyRegistered, // RegisterObserver
|
||||
kViENetworkObserverNotRegistered, // SetPeriodicDeadOrAliveStatus - Need to call RegisterObserver first, DeregisterObserver if no observer is registered.
|
||||
kViENetworkUnknownError, // An unknown error has occurred. Check the log file.
|
||||
|
||||
// ViERTP_RTCP.
|
||||
|
||||
@ -32,24 +32,6 @@ enum ViEPacketTimeout {
|
||||
PacketReceived = 1
|
||||
};
|
||||
|
||||
// This class declares an abstract interface for a user defined observer. It is
|
||||
// up to the VideoEngine user to implement a derived class which implements the
|
||||
// observer class. The observer is registered using RegisterObserver() and
|
||||
// deregistered using DeregisterObserver().
|
||||
class WEBRTC_DLLEXPORT ViENetworkObserver {
|
||||
public:
|
||||
// This method will be called periodically delivering a dead‐or‐alive
|
||||
// decision for a specified channel.
|
||||
virtual void OnPeriodicDeadOrAlive(const int video_channel,
|
||||
const bool alive) = 0;
|
||||
|
||||
// This method is called once if a packet timeout occurred.
|
||||
virtual void PacketTimeout(const int video_channel,
|
||||
const ViEPacketTimeout timeout) = 0;
|
||||
protected:
|
||||
virtual ~ViENetworkObserver() {}
|
||||
};
|
||||
|
||||
class WEBRTC_DLLEXPORT ViENetwork {
|
||||
public:
|
||||
// Default values.
|
||||
@ -96,27 +78,6 @@ class WEBRTC_DLLEXPORT ViENetwork {
|
||||
// over the network.
|
||||
virtual int SetMTU(int video_channel, unsigned int mtu) = 0;
|
||||
|
||||
// This function enables or disables warning reports if packets have not
|
||||
// been received for a specified time interval.
|
||||
virtual int SetPacketTimeoutNotification(const int video_channel,
|
||||
bool enable,
|
||||
int timeout_seconds) = 0;
|
||||
|
||||
// Registers an instance of a user implementation of the ViENetwork
|
||||
// observer.
|
||||
virtual int RegisterObserver(const int video_channel,
|
||||
ViENetworkObserver& observer) = 0;
|
||||
|
||||
// Removes a registered instance of ViENetworkObserver.
|
||||
virtual int DeregisterObserver(const int video_channel) = 0;
|
||||
|
||||
// This function enables or disables the periodic dead‐or‐alive callback
|
||||
// functionality for a specified channel.
|
||||
virtual int SetPeriodicDeadOrAliveStatus(
|
||||
const int video_channel,
|
||||
const bool enable,
|
||||
const unsigned int sample_time_seconds = KDefaultSampleTimeSeconds) = 0;
|
||||
|
||||
protected:
|
||||
ViENetwork() {}
|
||||
virtual ~ViENetwork() {}
|
||||
|
||||
@ -25,24 +25,6 @@
|
||||
#include <qos.h>
|
||||
#endif
|
||||
|
||||
class ViEAutoTestNetworkObserver: public webrtc::ViENetworkObserver
|
||||
{
|
||||
public:
|
||||
ViEAutoTestNetworkObserver()
|
||||
{
|
||||
}
|
||||
virtual ~ViEAutoTestNetworkObserver()
|
||||
{
|
||||
}
|
||||
virtual void OnPeriodicDeadOrAlive(const int videoChannel, const bool alive)
|
||||
{
|
||||
}
|
||||
virtual void PacketTimeout(const int videoChannel,
|
||||
const webrtc::ViEPacketTimeout timeout)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void ViEAutoTest::ViENetworkStandardTest()
|
||||
{
|
||||
TbInterfaces ViE("ViENetworkStandardTest"); // Create VIE
|
||||
@ -545,26 +527,6 @@ void ViEAutoTest::ViENetworkAPITest()
|
||||
EXPECT_NE(0, ViE.network->SetMTU(tbChannel.videoChannel, 1600));
|
||||
// Valid input
|
||||
EXPECT_EQ(0, ViE.network->SetMTU(tbChannel.videoChannel, 800));
|
||||
|
||||
//
|
||||
// Observer and timeout
|
||||
//
|
||||
ViEAutoTestNetworkObserver vieTestObserver;
|
||||
EXPECT_EQ(0, ViE.network->RegisterObserver(
|
||||
tbChannel.videoChannel, vieTestObserver));
|
||||
EXPECT_NE(0, ViE.network->RegisterObserver(
|
||||
tbChannel.videoChannel, vieTestObserver));
|
||||
EXPECT_EQ(0, ViE.network->SetPeriodicDeadOrAliveStatus(
|
||||
tbChannel.videoChannel, true)); // No observer
|
||||
EXPECT_EQ(0, ViE.network->DeregisterObserver(tbChannel.videoChannel));
|
||||
|
||||
EXPECT_NE(0, ViE.network->DeregisterObserver(tbChannel.videoChannel));
|
||||
EXPECT_NE(0, ViE.network->SetPeriodicDeadOrAliveStatus(
|
||||
tbChannel.videoChannel, true)); // No observer
|
||||
|
||||
// Packet timout notification
|
||||
EXPECT_EQ(0, ViE.network->SetPacketTimeoutNotification(
|
||||
tbChannel.videoChannel, true, 10));
|
||||
}
|
||||
|
||||
//***************************************************************
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "webrtc/modules/pacing/include/paced_sender.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
#include "webrtc/modules/utility/interface/process_thread.h"
|
||||
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
|
||||
@ -74,7 +75,7 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
||||
default_rtp_rtcp_(default_rtp_rtcp),
|
||||
rtp_rtcp_(NULL),
|
||||
vcm_(*VideoCodingModule::Create(ViEModuleId(engine_id, channel_id))),
|
||||
vie_receiver_(channel_id, &vcm_, remote_bitrate_estimator),
|
||||
vie_receiver_(channel_id, &vcm_, remote_bitrate_estimator, this),
|
||||
vie_sender_(channel_id),
|
||||
vie_sync_(&vcm_, this),
|
||||
stats_observer_(new ChannelStatsObserver(this)),
|
||||
@ -83,16 +84,13 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
||||
do_key_frame_callbackRequest_(false),
|
||||
rtp_observer_(NULL),
|
||||
rtcp_observer_(NULL),
|
||||
networkObserver_(NULL),
|
||||
intra_frame_observer_(intra_frame_observer),
|
||||
rtt_observer_(rtt_observer),
|
||||
paced_sender_(paced_sender),
|
||||
bandwidth_observer_(bandwidth_observer),
|
||||
rtp_packet_timeout_(false),
|
||||
send_timestamp_extension_id_(kInvalidRtpExtensionId),
|
||||
absolute_send_time_extension_id_(kInvalidRtpExtensionId),
|
||||
receive_absolute_send_time_enabled_(false),
|
||||
using_packet_spread_(false),
|
||||
external_transport_(NULL),
|
||||
decoder_reset_(true),
|
||||
wait_for_key_frame_(false),
|
||||
@ -112,8 +110,6 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
||||
configuration.id = ViEModuleId(engine_id, channel_id);
|
||||
configuration.audio = false;
|
||||
configuration.default_module = default_rtp_rtcp;
|
||||
configuration.incoming_data = &vie_receiver_;
|
||||
configuration.incoming_messages = this;
|
||||
configuration.outgoing_transport = &vie_sender_;
|
||||
configuration.rtcp_feedback = this;
|
||||
configuration.intra_frame_callback = intra_frame_observer;
|
||||
@ -121,6 +117,7 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
||||
configuration.rtt_observer = rtt_observer;
|
||||
configuration.remote_bitrate_estimator = remote_bitrate_estimator;
|
||||
configuration.paced_sender = paced_sender;
|
||||
configuration.receive_statistics = vie_receiver_.GetReceiveStatistics();
|
||||
|
||||
rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
|
||||
vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
|
||||
@ -132,6 +129,13 @@ int32_t ViEChannel::Init() {
|
||||
"%s: channel_id: %d, engine_id: %d)", __FUNCTION__, channel_id_,
|
||||
engine_id_);
|
||||
|
||||
if (module_process_thread_.RegisterModule(
|
||||
vie_receiver_.GetReceiveStatistics()) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Failed to register receive-statistics to process thread",
|
||||
__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
// RTP/RTCP initialization.
|
||||
if (rtp_rtcp_->SetSendingMediaStatus(false) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
@ -197,7 +201,10 @@ int32_t ViEChannel::Init() {
|
||||
VideoCodec video_codec;
|
||||
if (vcm_.Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
|
||||
rtp_rtcp_->RegisterSendPayload(video_codec);
|
||||
rtp_rtcp_->RegisterReceivePayload(video_codec);
|
||||
// TODO(holmer): Can we call SetReceiveCodec() here instead?
|
||||
if (!vie_receiver_.RegisterPayload(video_codec)) {
|
||||
return -1;
|
||||
}
|
||||
vcm_.RegisterReceiveCodec(&video_codec, number_of_cores_);
|
||||
vcm_.RegisterSendCodec(&video_codec, number_of_cores_,
|
||||
rtp_rtcp_->MaxDataPayloadLength());
|
||||
@ -215,6 +222,7 @@ ViEChannel::~ViEChannel() {
|
||||
channel_id_, engine_id_);
|
||||
|
||||
// Make sure we don't get more callbacks from the RTP module.
|
||||
module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics());
|
||||
module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
|
||||
module_process_thread_.DeRegisterModule(&vcm_);
|
||||
module_process_thread_.DeRegisterModule(&vie_sync_);
|
||||
@ -270,7 +278,6 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
(*it)->SetSendingMediaStatus(false);
|
||||
}
|
||||
}
|
||||
NACKMethod nack_method = rtp_rtcp_->NACK();
|
||||
|
||||
bool fec_enabled = false;
|
||||
uint8_t payload_type_red;
|
||||
@ -317,12 +324,12 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
|
||||
}
|
||||
if (nack_method != kNackOff) {
|
||||
if (rtp_rtcp_->StorePackets()) {
|
||||
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||
rtp_rtcp->SetNACKStatus(nack_method, max_nack_reordering_threshold_);
|
||||
} else if (paced_sender_) {
|
||||
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||
}
|
||||
|
||||
if (fec_enabled) {
|
||||
rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red,
|
||||
payload_type_fec);
|
||||
@ -444,12 +451,7 @@ int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s", __FUNCTION__);
|
||||
|
||||
int8_t old_pltype = -1;
|
||||
if (rtp_rtcp_->ReceivePayloadType(video_codec, &old_pltype) != -1) {
|
||||
rtp_rtcp_->DeRegisterReceivePayload(old_pltype);
|
||||
}
|
||||
|
||||
if (rtp_rtcp_->RegisterReceivePayload(video_codec) != 0) {
|
||||
if (!vie_receiver_.SetReceiveCodec(video_codec)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not register receive payload type", __FUNCTION__);
|
||||
return -1;
|
||||
@ -659,8 +661,8 @@ int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
|
||||
"%s: Could not enable NACK, RTPC not on ", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
if (rtp_rtcp_->SetNACKStatus(nackMethod,
|
||||
max_nack_reordering_threshold_) != 0) {
|
||||
if (!vie_receiver_.SetNackStatus(true,
|
||||
max_nack_reordering_threshold_)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not set NACK method %d", __FUNCTION__,
|
||||
nackMethod);
|
||||
@ -678,7 +680,6 @@ int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
|
||||
it != simulcast_rtp_rtcp_.end();
|
||||
it++) {
|
||||
RtpRtcp* rtp_rtcp = *it;
|
||||
rtp_rtcp->SetNACKStatus(nackMethod, max_nack_reordering_threshold_);
|
||||
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||
}
|
||||
// Don't introduce errors when NACK is enabled.
|
||||
@ -692,14 +693,13 @@ int32_t ViEChannel::ProcessNACKRequest(const bool enable) {
|
||||
if (paced_sender_ == NULL) {
|
||||
rtp_rtcp->SetStorePacketsStatus(false, 0);
|
||||
}
|
||||
rtp_rtcp->SetNACKStatus(kNackOff, max_nack_reordering_threshold_);
|
||||
}
|
||||
vcm_.RegisterPacketRequestCallback(NULL);
|
||||
if (paced_sender_ == NULL) {
|
||||
rtp_rtcp_->SetStorePacketsStatus(false, 0);
|
||||
}
|
||||
if (rtp_rtcp_->SetNACKStatus(kNackOff,
|
||||
max_nack_reordering_threshold_) != 0) {
|
||||
if (!vie_receiver_.SetNackStatus(false,
|
||||
max_nack_reordering_threshold_)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not turn off NACK", __FUNCTION__);
|
||||
return -1;
|
||||
@ -982,14 +982,15 @@ int32_t ViEChannel::SetSSRC(const uint32_t SSRC,
|
||||
}
|
||||
|
||||
int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
|
||||
const uint32_t SSRC) const {
|
||||
const uint32_t SSRC) {
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo,
|
||||
webrtc::kTraceVideo,
|
||||
ViEId(engine_id_, channel_id_),
|
||||
"%s(usage:%d, SSRC: 0x%x)",
|
||||
__FUNCTION__, usage, SSRC);
|
||||
|
||||
return rtp_rtcp_->SetRTXReceiveStatus(true, SSRC);
|
||||
vie_receiver_.SetRtxStatus(true, SSRC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(mflodman) Add kViEStreamTypeRtx.
|
||||
@ -1019,7 +1020,7 @@ int32_t ViEChannel::GetRemoteSSRC(uint32_t* ssrc) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
|
||||
*ssrc = rtp_rtcp_->RemoteSSRC();
|
||||
*ssrc = vie_receiver_.GetRemoteSsrc();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1030,7 +1031,7 @@ int32_t ViEChannel::GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]) {
|
||||
uint32_t arrayCSRC[kRtpCsrcSize];
|
||||
memset(arrayCSRC, 0, sizeof(arrayCSRC));
|
||||
|
||||
int num_csrcs = rtp_rtcp_->RemoteCSRCs(arrayCSRC);
|
||||
int num_csrcs = vie_receiver_.GetCsrcs(arrayCSRC);
|
||||
if (num_csrcs > 0) {
|
||||
memcpy(CSRCs, arrayCSRC, num_csrcs * sizeof(uint32_t));
|
||||
for (int idx = 0; idx < num_csrcs; idx++) {
|
||||
@ -1060,12 +1061,7 @@ int ViEChannel::SetRtxSendPayloadType(int payload_type) {
|
||||
}
|
||||
|
||||
void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
|
||||
rtp_rtcp_->SetRtxReceivePayloadType(payload_type);
|
||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
|
||||
it != simulcast_rtp_rtcp_.end(); it++) {
|
||||
(*it)->SetRtxReceivePayloadType(payload_type);
|
||||
}
|
||||
vie_receiver_.SetRtxPayloadType(payload_type);
|
||||
}
|
||||
|
||||
int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) {
|
||||
@ -1101,7 +1097,7 @@ int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
|
||||
uint32_t remoteSSRC = rtp_rtcp_->RemoteSSRC();
|
||||
uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
|
||||
return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname);
|
||||
}
|
||||
|
||||
@ -1208,7 +1204,7 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
|
||||
// it++) {
|
||||
// RtpRtcp* rtp_rtcp = *it;
|
||||
// }
|
||||
uint32_t remote_ssrc = rtp_rtcp_->RemoteSSRC();
|
||||
uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
|
||||
|
||||
// Get all RTCP receiver report blocks that have been received on this
|
||||
// channel. If we receive RTP packets from a remote source we know the
|
||||
@ -1251,24 +1247,33 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(holmer): This is a bad function name as it implies that it returns the
|
||||
// received RTCP, while it actually returns the statistics which will be sent
|
||||
// in the RTCP.
|
||||
int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
|
||||
uint32_t* cumulative_lost,
|
||||
uint32_t* extended_max,
|
||||
uint32_t* jitter_samples,
|
||||
int32_t* rtt_ms) {
|
||||
uint32_t* cumulative_lost,
|
||||
uint32_t* extended_max,
|
||||
uint32_t* jitter_samples,
|
||||
int32_t* rtt_ms) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s", __FUNCTION__);
|
||||
|
||||
uint8_t frac_lost = 0;
|
||||
if (rtp_rtcp_->StatisticsRTP(&frac_lost, cumulative_lost, extended_max,
|
||||
jitter_samples) != 0) {
|
||||
ReceiveStatistics* receive_statistics = vie_receiver_.GetReceiveStatistics();
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (!receive_statistics || !receive_statistics->Statistics(
|
||||
&receive_stats, rtp_rtcp_->RTCP() == kRtcpOff)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not get received RTP statistics", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
*fraction_lost = receive_stats.fraction_lost;
|
||||
*cumulative_lost = receive_stats.cumulative_lost;
|
||||
*extended_max = receive_stats.extended_max_sequence_number;
|
||||
*jitter_samples = receive_stats.jitter;
|
||||
*fraction_lost = frac_lost;
|
||||
|
||||
uint32_t remote_ssrc = rtp_rtcp_->RemoteSSRC();
|
||||
uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
|
||||
uint16_t dummy = 0;
|
||||
uint16_t rtt = 0;
|
||||
if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) {
|
||||
@ -1280,16 +1285,15 @@ int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
|
||||
}
|
||||
|
||||
int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
|
||||
uint32_t* packets_sent,
|
||||
uint32_t* bytes_received,
|
||||
uint32_t* packets_received) const {
|
||||
uint32_t* packets_sent,
|
||||
uint32_t* bytes_received,
|
||||
uint32_t* packets_received) const {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
|
||||
if (rtp_rtcp_->DataCountersRTP(bytes_sent,
|
||||
packets_sent,
|
||||
bytes_received,
|
||||
packets_received) != 0) {
|
||||
ReceiveStatistics* receive_statistics = vie_receiver_.GetReceiveStatistics();
|
||||
receive_statistics->GetDataCounters(bytes_received, packets_received);
|
||||
if (rtp_rtcp_->DataCountersRTP(bytes_sent, packets_sent) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not get counters", __FUNCTION__);
|
||||
return -1;
|
||||
@ -1301,7 +1305,7 @@ int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
|
||||
uint32_t bytes_sent_temp = 0;
|
||||
uint32_t packets_sent_temp = 0;
|
||||
RtpRtcp* rtp_rtcp = *it;
|
||||
rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp, NULL, NULL);
|
||||
rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
|
||||
bytes_sent += bytes_sent_temp;
|
||||
packets_sent += packets_sent_temp;
|
||||
}
|
||||
@ -1562,92 +1566,6 @@ uint16_t ViEChannel::MaxDataPayloadLength() const {
|
||||
return rtp_rtcp_->MaxDataPayloadLength();
|
||||
}
|
||||
|
||||
int32_t ViEChannel::SetPacketTimeoutNotification(
|
||||
bool enable, uint32_t timeout_seconds) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
if (enable) {
|
||||
uint32_t timeout_ms = 1000 * timeout_seconds;
|
||||
if (rtp_rtcp_->SetPacketTimeout(timeout_ms, 0) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (rtp_rtcp_->SetPacketTimeout(0, 0) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ViEChannel::RegisterNetworkObserver(
|
||||
ViENetworkObserver* observer) {
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (observer) {
|
||||
if (networkObserver_) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: observer alread added", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: observer added", __FUNCTION__);
|
||||
networkObserver_ = observer;
|
||||
} else {
|
||||
if (!networkObserver_) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: no observer added", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: observer removed", __FUNCTION__);
|
||||
networkObserver_ = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ViEChannel::NetworkObserverRegistered() {
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
return networkObserver_ != NULL;
|
||||
}
|
||||
|
||||
int32_t ViEChannel::SetPeriodicDeadOrAliveStatus(
|
||||
const bool enable, const uint32_t sample_time_seconds) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (!networkObserver_) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: no observer added", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool enabled = false;
|
||||
uint8_t current_sampletime_seconds = 0;
|
||||
|
||||
// Get old settings.
|
||||
rtp_rtcp_->PeriodicDeadOrAliveStatus(enabled, current_sampletime_seconds);
|
||||
// Set new settings.
|
||||
if (rtp_rtcp_->SetPeriodicDeadOrAliveStatus(
|
||||
enable, static_cast<uint8_t>(sample_time_seconds)) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not set periodic dead-or-alive status",
|
||||
__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
if (!enable) {
|
||||
// Restore last utilized sample time.
|
||||
// Without this trick, the sample time would always be reset to default
|
||||
// (2 sec), each time dead-or-alive was disabled without sample-time
|
||||
// parameter.
|
||||
rtp_rtcp_->SetPeriodicDeadOrAliveStatus(enable, current_sampletime_seconds);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ViEChannel::EnableColorEnhancement(bool enable) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s(enable: %d)", __FUNCTION__, enable);
|
||||
@ -1702,9 +1620,9 @@ int32_t ViEChannel::FrameToRender(
|
||||
}
|
||||
|
||||
uint32_t arr_ofCSRC[kRtpCsrcSize];
|
||||
int32_t no_of_csrcs = rtp_rtcp_->RemoteCSRCs(arr_ofCSRC);
|
||||
int32_t no_of_csrcs = vie_receiver_.GetCsrcs(arr_ofCSRC);
|
||||
if (no_of_csrcs <= 0) {
|
||||
arr_ofCSRC[0] = rtp_rtcp_->RemoteSSRC();
|
||||
arr_ofCSRC[0] = vie_receiver_.GetRemoteSsrc();
|
||||
no_of_csrcs = 1;
|
||||
}
|
||||
WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
@ -1728,8 +1646,8 @@ int32_t ViEChannel::StoreReceivedFrame(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ViEChannel::ReceiveStatistics(const uint32_t bit_rate,
|
||||
const uint32_t frame_rate) {
|
||||
int32_t ViEChannel::OnReceiveStatisticsUpdate(const uint32_t bit_rate,
|
||||
const uint32_t frame_rate) {
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (codec_observer_) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
@ -1882,8 +1800,10 @@ int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id,
|
||||
} else {
|
||||
module_process_thread_.DeRegisterModule(&vie_sync_);
|
||||
}
|
||||
return vie_sync_.ConfigureSync(ve_channel_id, ve_sync_interface,
|
||||
rtp_rtcp_.get());
|
||||
return vie_sync_.ConfigureSync(ve_channel_id,
|
||||
ve_sync_interface,
|
||||
rtp_rtcp_.get(),
|
||||
vie_receiver_.GetRtpReceiver());
|
||||
}
|
||||
|
||||
int32_t ViEChannel::VoiceChannel() {
|
||||
@ -1954,52 +1874,6 @@ int32_t ViEChannel::OnInitializeDecoder(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ViEChannel::OnPacketTimeout(const int32_t id) {
|
||||
assert(ChannelId(id) == channel_id_);
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (networkObserver_) {
|
||||
networkObserver_->PacketTimeout(channel_id_, NoPacket);
|
||||
rtp_packet_timeout_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ViEChannel::OnReceivedPacket(const int32_t id,
|
||||
const RtpRtcpPacketType packet_type) {
|
||||
assert(ChannelId(id) == channel_id_);
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
if (rtp_packet_timeout_ && packet_type == kPacketRtp) {
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (networkObserver_) {
|
||||
networkObserver_->PacketTimeout(channel_id_, PacketReceived);
|
||||
}
|
||||
|
||||
// Reset even if no observer set, might have been removed during timeout.
|
||||
rtp_packet_timeout_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ViEChannel::OnPeriodicDeadOrAlive(const int32_t id,
|
||||
const RTPAliveType alive) {
|
||||
assert(ChannelId(id) == channel_id_);
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s(id=%d, alive=%d)", __FUNCTION__, id, alive);
|
||||
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (!networkObserver_) {
|
||||
return;
|
||||
}
|
||||
bool is_alive = true;
|
||||
if (alive == kRtpDead) {
|
||||
is_alive = false;
|
||||
}
|
||||
networkObserver_->OnPeriodicDeadOrAlive(channel_id_, is_alive);
|
||||
return;
|
||||
}
|
||||
|
||||
void ViEChannel::OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC) {
|
||||
if (channel_id_ != ChannelId(id)) {
|
||||
@ -2012,6 +1886,8 @@ void ViEChannel::OnIncomingSSRCChanged(const int32_t id,
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: %u", __FUNCTION__, SSRC);
|
||||
|
||||
rtp_rtcp_->SetRemoteSSRC(SSRC);
|
||||
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
{
|
||||
if (rtp_observer_) {
|
||||
@ -2044,4 +1920,8 @@ void ViEChannel::OnIncomingCSRCChanged(const int32_t id,
|
||||
}
|
||||
}
|
||||
|
||||
void ViEChannel::ResetStatistics() {
|
||||
vie_receiver_.GetReceiveStatistics()->ResetStatistics();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -41,7 +41,6 @@ class RtpRtcp;
|
||||
class ThreadWrapper;
|
||||
class ViEDecoderObserver;
|
||||
class ViEEffectFilter;
|
||||
class ViENetworkObserver;
|
||||
class ViERTCPObserver;
|
||||
class ViERTPObserver;
|
||||
class VideoCodingModule;
|
||||
@ -209,16 +208,12 @@ class ViEChannel
|
||||
const int frequency,
|
||||
const uint8_t channels,
|
||||
const uint32_t rate);
|
||||
virtual void OnPacketTimeout(const int32_t id);
|
||||
virtual void OnReceivedPacket(const int32_t id,
|
||||
const RtpRtcpPacketType packet_type);
|
||||
virtual void OnPeriodicDeadOrAlive(const int32_t id,
|
||||
const RTPAliveType alive);
|
||||
virtual void OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC);
|
||||
virtual void OnIncomingCSRCChanged(const int32_t id,
|
||||
const uint32_t CSRC,
|
||||
const bool added);
|
||||
virtual void ResetStatistics();
|
||||
|
||||
int32_t SetLocalReceiver(const uint16_t rtp_port,
|
||||
const uint16_t rtcp_port,
|
||||
@ -241,7 +236,7 @@ class ViEChannel
|
||||
char* ip_address,
|
||||
uint32_t ip_address_length);
|
||||
|
||||
int32_t SetRemoteSSRCType(const StreamType usage, const uint32_t SSRC) const;
|
||||
int32_t SetRemoteSSRCType(const StreamType usage, const uint32_t SSRC);
|
||||
|
||||
int32_t StartSend();
|
||||
int32_t StopSend();
|
||||
@ -270,12 +265,6 @@ class ViEChannel
|
||||
int32_t SetMaxPacketBurstSize(uint16_t max_number_of_packets);
|
||||
int32_t SetPacketBurstSpreadState(bool enable, const uint16_t frame_periodMS);
|
||||
|
||||
int32_t SetPacketTimeoutNotification(bool enable, uint32_t timeout_seconds);
|
||||
int32_t RegisterNetworkObserver(ViENetworkObserver* observer);
|
||||
bool NetworkObserverRegistered();
|
||||
int32_t SetPeriodicDeadOrAliveStatus(
|
||||
const bool enable, const uint32_t sample_time_seconds);
|
||||
|
||||
int32_t EnableColorEnhancement(bool enable);
|
||||
|
||||
// Gets the modules used by the channel.
|
||||
@ -298,7 +287,7 @@ class ViEChannel
|
||||
const EncodedVideoData& frame_to_store);
|
||||
|
||||
// Implements VideoReceiveStatisticsCallback.
|
||||
virtual int32_t ReceiveStatistics(const uint32_t bit_rate,
|
||||
virtual int32_t OnReceiveStatisticsUpdate(const uint32_t bit_rate,
|
||||
const uint32_t frame_rate);
|
||||
|
||||
// Implements VideoFrameTypeCallback.
|
||||
@ -371,13 +360,11 @@ class ViEChannel
|
||||
bool do_key_frame_callbackRequest_;
|
||||
ViERTPObserver* rtp_observer_;
|
||||
ViERTCPObserver* rtcp_observer_;
|
||||
ViENetworkObserver* networkObserver_;
|
||||
RtcpIntraFrameObserver* intra_frame_observer_;
|
||||
RtcpRttObserver* rtt_observer_;
|
||||
PacedSender* paced_sender_;
|
||||
|
||||
scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
|
||||
bool rtp_packet_timeout_;
|
||||
int send_timestamp_extension_id_;
|
||||
int absolute_send_time_extension_id_;
|
||||
bool receive_absolute_send_time_enabled_;
|
||||
|
||||
@ -246,7 +246,7 @@ int ViECodecImpl::SetSendCodec(const int video_channel,
|
||||
shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
|
||||
|
||||
// Update the protection mode, we might be switching NACK/FEC.
|
||||
vie_encoder->UpdateProtectionMethod();
|
||||
vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled());
|
||||
|
||||
// Get new best format for frame provider.
|
||||
ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
|
||||
|
||||
@ -726,7 +726,7 @@ int ViEEncoder::CodecTargetBitrate(uint32_t* bitrate) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ViEEncoder::UpdateProtectionMethod() {
|
||||
int32_t ViEEncoder::UpdateProtectionMethod(bool enable_nack) {
|
||||
bool fec_enabled = false;
|
||||
uint8_t dummy_ptype_red = 0;
|
||||
uint8_t dummy_ptypeFEC = 0;
|
||||
@ -739,25 +739,23 @@ int32_t ViEEncoder::UpdateProtectionMethod() {
|
||||
if (error) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool nack_enabled = (default_rtp_rtcp_->NACK() == kNackOff) ? false : true;
|
||||
if (fec_enabled_ == fec_enabled && nack_enabled_ == nack_enabled) {
|
||||
if (fec_enabled_ == fec_enabled && nack_enabled_ == enable_nack) {
|
||||
// No change needed, we're already in correct state.
|
||||
return 0;
|
||||
}
|
||||
fec_enabled_ = fec_enabled;
|
||||
nack_enabled_ = nack_enabled;
|
||||
nack_enabled_ = enable_nack;
|
||||
|
||||
// Set Video Protection for VCM.
|
||||
if (fec_enabled && nack_enabled) {
|
||||
if (fec_enabled && nack_enabled_) {
|
||||
vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, true);
|
||||
} else {
|
||||
vcm_.SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_);
|
||||
vcm_.SetVideoProtection(webrtc::kProtectionNack, nack_enabled_);
|
||||
vcm_.SetVideoProtection(webrtc::kProtectionNackSender, nack_enabled_);
|
||||
vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, false);
|
||||
}
|
||||
|
||||
if (fec_enabled || nack_enabled) {
|
||||
if (fec_enabled_ || nack_enabled_) {
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(engine_id_, channel_id_), "%s: FEC status ",
|
||||
__FUNCTION__, fec_enabled);
|
||||
|
||||
@ -114,7 +114,8 @@ class ViEEncoder
|
||||
|
||||
int CodecTargetBitrate(uint32_t* bitrate) const;
|
||||
// Loss protection.
|
||||
int32_t UpdateProtectionMethod();
|
||||
int32_t UpdateProtectionMethod(bool enable_nack);
|
||||
bool nack_enabled() const { return nack_enabled_; }
|
||||
|
||||
// Buffering mode.
|
||||
void SetSenderBufferingMode(int target_delay_ms);
|
||||
|
||||
@ -196,99 +196,4 @@ int ViENetworkImpl::SetMTU(int video_channel, unsigned int mtu) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViENetworkImpl::SetPacketTimeoutNotification(const int video_channel,
|
||||
bool enable,
|
||||
int timeout_seconds) {
|
||||
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"%s(channel: %d, enable: %d, timeout_seconds: %u)",
|
||||
__FUNCTION__, video_channel, enable, timeout_seconds);
|
||||
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||
if (!vie_channel) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"Channel doesn't exist");
|
||||
shared_data_->SetLastError(kViENetworkInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
if (vie_channel->SetPacketTimeoutNotification(enable,
|
||||
timeout_seconds) != 0) {
|
||||
shared_data_->SetLastError(kViENetworkUnknownError);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViENetworkImpl::RegisterObserver(const int video_channel,
|
||||
ViENetworkObserver& observer) {
|
||||
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"%s(channel: %d)", __FUNCTION__, video_channel);
|
||||
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||
if (!vie_channel) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"Channel doesn't exist");
|
||||
shared_data_->SetLastError(kViENetworkInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
if (vie_channel->RegisterNetworkObserver(&observer) != 0) {
|
||||
shared_data_->SetLastError(kViENetworkObserverAlreadyRegistered);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViENetworkImpl::DeregisterObserver(const int video_channel) {
|
||||
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"%s(channel: %d)", __FUNCTION__, video_channel);
|
||||
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||
if (!vie_channel) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"Channel doesn't exist");
|
||||
shared_data_->SetLastError(kViENetworkInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
if (!vie_channel->NetworkObserverRegistered()) {
|
||||
shared_data_->SetLastError(kViENetworkObserverNotRegistered);
|
||||
return -1;
|
||||
}
|
||||
return vie_channel->RegisterNetworkObserver(NULL);
|
||||
}
|
||||
|
||||
int ViENetworkImpl::SetPeriodicDeadOrAliveStatus(
|
||||
const int video_channel,
|
||||
bool enable,
|
||||
unsigned int sample_time_seconds) {
|
||||
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"%s(channel: %d, enable: %d, sample_time_seconds: %ul)",
|
||||
__FUNCTION__, video_channel, enable, sample_time_seconds);
|
||||
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||
if (!vie_channel) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||
ViEId(shared_data_->instance_id(), video_channel),
|
||||
"Channel doesn't exist");
|
||||
shared_data_->SetLastError(kViENetworkInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
if (!vie_channel->NetworkObserverRegistered()) {
|
||||
shared_data_->SetLastError(kViENetworkObserverNotRegistered);
|
||||
return -1;
|
||||
}
|
||||
if (vie_channel->SetPeriodicDeadOrAliveStatus(enable, sample_time_seconds)
|
||||
!= 0) {
|
||||
shared_data_->SetLastError(kViENetworkUnknownError);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -37,16 +37,6 @@ class ViENetworkImpl
|
||||
const void* data,
|
||||
const int length);
|
||||
virtual int SetMTU(int video_channel, unsigned int mtu);
|
||||
virtual int SetPacketTimeoutNotification(const int video_channel,
|
||||
bool enable,
|
||||
int timeout_seconds);
|
||||
virtual int RegisterObserver(const int video_channel,
|
||||
ViENetworkObserver& observer);
|
||||
virtual int DeregisterObserver(const int video_channel);
|
||||
virtual int SetPeriodicDeadOrAliveStatus(
|
||||
const int video_channel,
|
||||
const bool enable,
|
||||
const unsigned int sample_time_seconds);
|
||||
|
||||
protected:
|
||||
explicit ViENetworkImpl(ViESharedData* shared_data);
|
||||
|
||||
@ -13,7 +13,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
#include "webrtc/modules/utility/interface/rtp_dump.h"
|
||||
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
|
||||
@ -25,10 +28,18 @@ namespace webrtc {
|
||||
|
||||
ViEReceiver::ViEReceiver(const int32_t channel_id,
|
||||
VideoCodingModule* module_vcm,
|
||||
RemoteBitrateEstimator* remote_bitrate_estimator)
|
||||
RemoteBitrateEstimator* remote_bitrate_estimator,
|
||||
RtpFeedback* rtp_feedback)
|
||||
: receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
channel_id_(channel_id),
|
||||
rtp_header_parser_(RtpHeaderParser::Create()),
|
||||
rtp_payload_registry_(new RTPPayloadRegistry(
|
||||
channel_id, RTPPayloadStrategy::CreateStrategy(false))),
|
||||
rtp_receiver_(RtpReceiver::CreateVideoReceiver(
|
||||
channel_id, Clock::GetRealTimeClock(), this, rtp_feedback,
|
||||
rtp_payload_registry_.get())),
|
||||
rtp_receive_statistics_(ReceiveStatistics::Create(
|
||||
Clock::GetRealTimeClock())),
|
||||
rtp_rtcp_(NULL),
|
||||
vcm_(module_vcm),
|
||||
remote_bitrate_estimator_(remote_bitrate_estimator),
|
||||
@ -51,6 +62,49 @@ ViEReceiver::~ViEReceiver() {
|
||||
}
|
||||
}
|
||||
|
||||
bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) {
|
||||
int8_t old_pltype = -1;
|
||||
if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName,
|
||||
kVideoPayloadTypeFrequency,
|
||||
0,
|
||||
video_codec.maxBitrate,
|
||||
&old_pltype) != -1) {
|
||||
rtp_payload_registry_->DeRegisterReceivePayload(old_pltype);
|
||||
}
|
||||
|
||||
return RegisterPayload(video_codec);
|
||||
}
|
||||
|
||||
bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) {
|
||||
return rtp_receiver_->RegisterReceivePayload(video_codec.plName,
|
||||
video_codec.plType,
|
||||
kVideoPayloadTypeFrequency,
|
||||
0,
|
||||
video_codec.maxBitrate) == 0;
|
||||
}
|
||||
|
||||
bool ViEReceiver::SetNackStatus(bool enable,
|
||||
int max_nack_reordering_threshold) {
|
||||
return rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff,
|
||||
max_nack_reordering_threshold) == 0;
|
||||
}
|
||||
|
||||
void ViEReceiver::SetRtxStatus(bool enable, uint32_t ssrc) {
|
||||
rtp_receiver_->SetRTXStatus(true, ssrc);
|
||||
}
|
||||
|
||||
void ViEReceiver::SetRtxPayloadType(uint32_t payload_type) {
|
||||
rtp_receiver_->SetRtxPayloadType(payload_type);
|
||||
}
|
||||
|
||||
uint32_t ViEReceiver::GetRemoteSsrc() const {
|
||||
return rtp_receiver_->SSRC();
|
||||
}
|
||||
|
||||
int ViEReceiver::GetCsrcs(uint32_t* csrcs) const {
|
||||
return rtp_receiver_->CSRCs(csrcs);
|
||||
}
|
||||
|
||||
int ViEReceiver::RegisterExternalDecryption(Encryption* decryption) {
|
||||
CriticalSectionScoped cs(receive_cs_.get());
|
||||
if (external_decryption_) {
|
||||
@ -77,6 +131,10 @@ void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) {
|
||||
rtp_rtcp_ = module;
|
||||
}
|
||||
|
||||
RtpReceiver* ViEReceiver::GetRtpReceiver() const {
|
||||
return rtp_receiver_.get();
|
||||
}
|
||||
|
||||
void ViEReceiver::RegisterSimulcastRtpRtcpModules(
|
||||
const std::list<RtpRtcp*>& rtp_modules) {
|
||||
CriticalSectionScoped cs(receive_cs_.get());
|
||||
@ -134,6 +192,25 @@ int32_t ViEReceiver::OnReceivedPayloadData(
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
|
||||
int rtp_packet_length) {
|
||||
RTPHeader header;
|
||||
if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
|
||||
WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVideo, channel_id_,
|
||||
"IncomingPacket invalid RTP header");
|
||||
return false;
|
||||
}
|
||||
header.payload_type_frequency = kVideoPayloadTypeFrequency;
|
||||
PayloadUnion payload_specific;
|
||||
if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
|
||||
&payload_specific)) {
|
||||
return false;
|
||||
}
|
||||
return rtp_receiver_->IncomingRtpPacket(&header, rtp_packet,
|
||||
rtp_packet_length,
|
||||
payload_specific, false);
|
||||
}
|
||||
|
||||
int ViEReceiver::InsertRTPPacket(const int8_t* rtp_packet,
|
||||
int rtp_packet_length) {
|
||||
// TODO(mflodman) Change decrypt to get rid of this cast.
|
||||
@ -182,9 +259,19 @@ int ViEReceiver::InsertRTPPacket(const int8_t* rtp_packet,
|
||||
const int payload_size = received_packet_length - header.headerLength;
|
||||
remote_bitrate_estimator_->IncomingPacket(TickTime::MillisecondTimestamp(),
|
||||
payload_size, header);
|
||||
assert(rtp_rtcp_); // Should be set by owner at construction time.
|
||||
return rtp_rtcp_->IncomingRtpPacket(received_packet, received_packet_length,
|
||||
header);
|
||||
header.payload_type_frequency = kVideoPayloadTypeFrequency;
|
||||
bool in_order = rtp_receiver_->InOrderPacket(header.sequenceNumber);
|
||||
bool retransmitted = !in_order && IsPacketRetransmitted(header);
|
||||
rtp_receive_statistics_->IncomingPacket(header, received_packet_length,
|
||||
retransmitted, in_order);
|
||||
PayloadUnion payload_specific;
|
||||
if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
|
||||
&payload_specific)) {
|
||||
return -1;
|
||||
}
|
||||
return rtp_receiver_->IncomingRtpPacket(&header, received_packet,
|
||||
received_packet_length,
|
||||
payload_specific, in_order) ? 0 : -1;
|
||||
}
|
||||
|
||||
int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet,
|
||||
@ -298,7 +385,7 @@ void ViEReceiver::EstimatedReceiveBandwidth(
|
||||
// LatestEstimate returns an error if there is no valid bitrate estimate, but
|
||||
// ViEReceiver instead returns a zero estimate.
|
||||
remote_bitrate_estimator_->LatestEstimate(&ssrcs, available_bandwidth);
|
||||
if (std::find(ssrcs.begin(), ssrcs.end(), rtp_rtcp_->RemoteSSRC()) !=
|
||||
if (std::find(ssrcs.begin(), ssrcs.end(), rtp_receiver_->SSRC()) !=
|
||||
ssrcs.end()) {
|
||||
*available_bandwidth /= ssrcs.size();
|
||||
} else {
|
||||
@ -306,4 +393,25 @@ void ViEReceiver::EstimatedReceiveBandwidth(
|
||||
}
|
||||
}
|
||||
|
||||
ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const {
|
||||
return rtp_receive_statistics_.get();
|
||||
}
|
||||
|
||||
bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header) const {
|
||||
bool rtx_enabled = false;
|
||||
uint32_t rtx_ssrc = 0;
|
||||
int rtx_payload_type = 0;
|
||||
rtp_receiver_->RTXStatus(&rtx_enabled, &rtx_ssrc, &rtx_payload_type);
|
||||
if (!rtx_enabled) {
|
||||
// Check if this is a retransmission.
|
||||
ReceiveStatistics::RtpReceiveStatistics stats;
|
||||
if (rtp_receive_statistics_->Statistics(&stats, false)) {
|
||||
uint16_t min_rtt = 0;
|
||||
rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
|
||||
return rtp_receiver_->RetransmitOfOldPacket(header, stats.jitter,
|
||||
min_rtt);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include <list>
|
||||
|
||||
#include "webrtc/engine_configurations.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
@ -23,23 +24,39 @@ namespace webrtc {
|
||||
|
||||
class CriticalSectionWrapper;
|
||||
class Encryption;
|
||||
class ReceiveStatistics;
|
||||
class RemoteBitrateEstimator;
|
||||
class RtpDump;
|
||||
class RtpHeaderParser;
|
||||
class RTPPayloadRegistry;
|
||||
class RtpReceiver;
|
||||
class RtpRtcp;
|
||||
class VideoCodingModule;
|
||||
|
||||
class ViEReceiver : public RtpData {
|
||||
public:
|
||||
ViEReceiver(const int32_t channel_id, VideoCodingModule* module_vcm,
|
||||
RemoteBitrateEstimator* remote_bitrate_estimator);
|
||||
RemoteBitrateEstimator* remote_bitrate_estimator,
|
||||
RtpFeedback* rtp_feedback);
|
||||
~ViEReceiver();
|
||||
|
||||
bool SetReceiveCodec(const VideoCodec& video_codec);
|
||||
bool RegisterPayload(const VideoCodec& video_codec);
|
||||
|
||||
bool SetNackStatus(bool enable, int max_nack_reordering_threshold);
|
||||
void SetRtxStatus(bool enable, uint32_t ssrc);
|
||||
void SetRtxPayloadType(uint32_t payload_type);
|
||||
|
||||
uint32_t GetRemoteSsrc() const;
|
||||
int GetCsrcs(uint32_t* csrcs) const;
|
||||
|
||||
int RegisterExternalDecryption(Encryption* decryption);
|
||||
int DeregisterExternalDecryption();
|
||||
|
||||
void SetRtpRtcpModule(RtpRtcp* module);
|
||||
|
||||
RtpReceiver* GetRtpReceiver() const;
|
||||
|
||||
void RegisterSimulcastRtpRtcpModules(const std::list<RtpRtcp*>& rtp_modules);
|
||||
|
||||
bool SetReceiveTimestampOffsetStatus(bool enable, int id);
|
||||
@ -54,6 +71,8 @@ class ViEReceiver : public RtpData {
|
||||
// Receives packets from external transport.
|
||||
int ReceivedRTPPacket(const void* rtp_packet, int rtp_packet_length);
|
||||
int ReceivedRTCPPacket(const void* rtcp_packet, int rtcp_packet_length);
|
||||
virtual bool OnRecoveredPacket(const uint8_t* packet,
|
||||
int packet_length) OVERRIDE;
|
||||
|
||||
// Implements RtpData.
|
||||
virtual int32_t OnReceivedPayloadData(
|
||||
@ -63,13 +82,19 @@ class ViEReceiver : public RtpData {
|
||||
|
||||
void EstimatedReceiveBandwidth(unsigned int* available_bandwidth) const;
|
||||
|
||||
ReceiveStatistics* GetReceiveStatistics() const;
|
||||
|
||||
private:
|
||||
int InsertRTPPacket(const int8_t* rtp_packet, int rtp_packet_length);
|
||||
int InsertRTCPPacket(const int8_t* rtcp_packet, int rtcp_packet_length);
|
||||
bool IsPacketRetransmitted(const RTPHeader& header) const;
|
||||
|
||||
scoped_ptr<CriticalSectionWrapper> receive_cs_;
|
||||
const int32_t channel_id_;
|
||||
scoped_ptr<RtpHeaderParser> rtp_header_parser_;
|
||||
scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
|
||||
scoped_ptr<RtpReceiver> rtp_receiver_;
|
||||
scoped_ptr<ReceiveStatistics> rtp_receive_statistics_;
|
||||
RtpRtcp* rtp_rtcp_;
|
||||
std::list<RtpRtcp*> rtp_rtcp_simulcast_;
|
||||
VideoCodingModule* vcm_;
|
||||
|
||||
@ -501,7 +501,7 @@ int ViERTP_RTCPImpl::SetNACKStatus(const int video_channel, const bool enable) {
|
||||
shared_data_->SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
vie_encoder->UpdateProtectionMethod();
|
||||
vie_encoder->UpdateProtectionMethod(enable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -542,7 +542,7 @@ int ViERTP_RTCPImpl::SetFECStatus(const int video_channel, const bool enable,
|
||||
shared_data_->SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
vie_encoder->UpdateProtectionMethod();
|
||||
vie_encoder->UpdateProtectionMethod(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -587,7 +587,7 @@ int ViERTP_RTCPImpl::SetHybridNACKFECStatus(
|
||||
shared_data_->SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
vie_encoder->UpdateProtectionMethod();
|
||||
vie_encoder->UpdateProtectionMethod(enable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "webrtc/video_engine/vie_sync_module.h"
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
@ -24,15 +25,15 @@ namespace webrtc {
|
||||
enum { kSyncInterval = 1000};
|
||||
|
||||
int UpdateMeasurements(StreamSynchronization::Measurements* stream,
|
||||
const RtpRtcp* rtp_rtcp) {
|
||||
stream->latest_timestamp = rtp_rtcp->RemoteTimestamp();
|
||||
stream->latest_receive_time_ms = rtp_rtcp->LocalTimeOfRemoteTimeStamp();
|
||||
const RtpRtcp& rtp_rtcp, const RtpReceiver& receiver) {
|
||||
stream->latest_timestamp = receiver.Timestamp();
|
||||
stream->latest_receive_time_ms = receiver.LastReceivedTimeMs();
|
||||
synchronization::RtcpMeasurement measurement;
|
||||
if (0 != rtp_rtcp->RemoteNTP(&measurement.ntp_secs,
|
||||
&measurement.ntp_frac,
|
||||
NULL,
|
||||
NULL,
|
||||
&measurement.rtp_timestamp)) {
|
||||
if (0 != rtp_rtcp.RemoteNTP(&measurement.ntp_secs,
|
||||
&measurement.ntp_frac,
|
||||
NULL,
|
||||
NULL,
|
||||
&measurement.rtp_timestamp)) {
|
||||
return -1;
|
||||
}
|
||||
if (measurement.ntp_secs == 0 && measurement.ntp_frac == 0) {
|
||||
@ -60,6 +61,7 @@ ViESyncModule::ViESyncModule(VideoCodingModule* vcm,
|
||||
: data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
vcm_(vcm),
|
||||
vie_channel_(vie_channel),
|
||||
video_receiver_(NULL),
|
||||
video_rtp_rtcp_(NULL),
|
||||
voe_channel_id_(-1),
|
||||
voe_sync_interface_(NULL),
|
||||
@ -72,10 +74,12 @@ ViESyncModule::~ViESyncModule() {
|
||||
|
||||
int ViESyncModule::ConfigureSync(int voe_channel_id,
|
||||
VoEVideoSync* voe_sync_interface,
|
||||
RtpRtcp* video_rtcp_module) {
|
||||
RtpRtcp* video_rtcp_module,
|
||||
RtpReceiver* video_receiver) {
|
||||
CriticalSectionScoped cs(data_cs_.get());
|
||||
voe_channel_id_ = voe_channel_id;
|
||||
voe_sync_interface_ = voe_sync_interface;
|
||||
video_receiver_ = video_receiver;
|
||||
video_rtp_rtcp_ = video_rtcp_module;
|
||||
sync_.reset(new StreamSynchronization(voe_channel_id, vie_channel_->Id()));
|
||||
|
||||
@ -129,16 +133,21 @@ int32_t ViESyncModule::Process() {
|
||||
playout_buffer_delay_ms;
|
||||
|
||||
RtpRtcp* voice_rtp_rtcp = NULL;
|
||||
if (0 != voe_sync_interface_->GetRtpRtcp(voe_channel_id_, voice_rtp_rtcp)) {
|
||||
RtpReceiver* voice_receiver = NULL;
|
||||
if (0 != voe_sync_interface_->GetRtpRtcp(voe_channel_id_, &voice_rtp_rtcp,
|
||||
&voice_receiver)) {
|
||||
return 0;
|
||||
}
|
||||
assert(voice_rtp_rtcp);
|
||||
assert(voice_receiver);
|
||||
|
||||
if (UpdateMeasurements(&video_measurement_, video_rtp_rtcp_) != 0) {
|
||||
if (UpdateMeasurements(&video_measurement_, *video_rtp_rtcp_,
|
||||
*video_receiver_) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (UpdateMeasurements(&audio_measurement_, voice_rtp_rtcp) != 0) {
|
||||
if (UpdateMeasurements(&audio_measurement_, *voice_rtp_rtcp,
|
||||
*voice_receiver) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,8 @@ class ViESyncModule : public Module {
|
||||
|
||||
int ConfigureSync(int voe_channel_id,
|
||||
VoEVideoSync* voe_sync_interface,
|
||||
RtpRtcp* video_rtcp_module);
|
||||
RtpRtcp* video_rtcp_module,
|
||||
RtpReceiver* video_receiver);
|
||||
|
||||
int VoiceChannel();
|
||||
|
||||
@ -51,6 +52,7 @@ class ViESyncModule : public Module {
|
||||
scoped_ptr<CriticalSectionWrapper> data_cs_;
|
||||
VideoCodingModule* vcm_;
|
||||
ViEChannel* vie_channel_;
|
||||
RtpReceiver* video_receiver_;
|
||||
RtpRtcp* video_rtp_rtcp_;
|
||||
int voe_channel_id_;
|
||||
VoEVideoSync* voe_sync_interface_;
|
||||
|
||||
Reference in New Issue
Block a user