blob: 36e60040de084a70292b14e9353ebaf4f3e6bca0 [file] [log] [blame]
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/video_engine/vie_rtp_rtcp_impl.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/system_wrappers/interface/file_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/video_engine/include/vie_errors.h"
#include "webrtc/video_engine/vie_channel.h"
#include "webrtc/video_engine/vie_channel_manager.h"
#include "webrtc/video_engine/vie_defines.h"
#include "webrtc/video_engine/vie_encoder.h"
#include "webrtc/video_engine/vie_impl.h"
#include "webrtc/video_engine/vie_shared_data.h"
namespace webrtc {
// Helper methods for converting between module format and ViE API format.
static RTCPMethod ViERTCPModeToRTCPMethod(ViERTCPMode api_mode) {
switch (api_mode) {
case kRtcpNone:
return kRtcpOff;
case kRtcpCompound_RFC4585:
return kRtcpCompound;
case kRtcpNonCompound_RFC5506:
return kRtcpNonCompound;
}
assert(false);
return kRtcpOff;
}
static ViERTCPMode RTCPMethodToViERTCPMode(RTCPMethod module_method) {
switch (module_method) {
case kRtcpOff:
return kRtcpNone;
case kRtcpCompound:
return kRtcpCompound_RFC4585;
case kRtcpNonCompound:
return kRtcpNonCompound_RFC5506;
}
assert(false);
return kRtcpNone;
}
static KeyFrameRequestMethod APIRequestToModuleRequest(
ViEKeyFrameRequestMethod api_method) {
switch (api_method) {
case kViEKeyFrameRequestNone:
return kKeyFrameReqFirRtp;
case kViEKeyFrameRequestPliRtcp:
return kKeyFrameReqPliRtcp;
case kViEKeyFrameRequestFirRtp:
return kKeyFrameReqFirRtp;
case kViEKeyFrameRequestFirRtcp:
return kKeyFrameReqFirRtcp;
}
assert(false);
return kKeyFrameReqFirRtp;
}
ViERTP_RTCP* ViERTP_RTCP::GetInterface(VideoEngine* video_engine) {
#ifdef WEBRTC_VIDEO_ENGINE_RTP_RTCP_API
if (!video_engine) {
return NULL;
}
VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
ViERTP_RTCPImpl* vie_rtpimpl = vie_impl;
// Increase ref count.
(*vie_rtpimpl)++;
return vie_rtpimpl;
#else
return NULL;
#endif
}
int ViERTP_RTCPImpl::Release() {
// Decrease ref count.
(*this)--;
int32_t ref_count = GetCount();
if (ref_count < 0) {
LOG(LS_ERROR) << "ViERTP_RTCP released too many times.";
shared_data_->SetLastError(kViEAPIDoesNotExist);
return -1;
}
return ref_count;
}
ViERTP_RTCPImpl::ViERTP_RTCPImpl(ViESharedData* shared_data)
: shared_data_(shared_data) {}
ViERTP_RTCPImpl::~ViERTP_RTCPImpl() {}
int ViERTP_RTCPImpl::SetLocalSSRC(const int video_channel,
const unsigned int SSRC,
const StreamType usage,
const unsigned char simulcast_idx) {
LOG_F(LS_INFO) << "channel: " << video_channel << " ssrc: " << SSRC << "";
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetSSRC(SSRC, usage, simulcast_idx) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetRemoteSSRCType(const int videoChannel,
const StreamType usage,
const unsigned int SSRC) const {
LOG_F(LS_INFO) << "channel: " << videoChannel
<< " usage: " << static_cast<int>(usage) << " ssrc: " << SSRC;
// Get the channel
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
if (ptrViEChannel == NULL) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (ptrViEChannel->SetRemoteSSRCType(usage, SSRC) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetLocalSSRC(const int video_channel,
unsigned int& SSRC) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
uint8_t idx = 0;
if (vie_channel->GetLocalSSRC(idx, &SSRC) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetRemoteSSRC(const int video_channel,
unsigned int& SSRC) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->GetRemoteSSRC(&SSRC) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetRemoteCSRCs(const int video_channel,
unsigned int CSRCs[kRtpCsrcSize]) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->GetRemoteCSRC(CSRCs) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetRtxSendPayloadType(const int video_channel,
const uint8_t payload_type) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " payload_type: " << static_cast<int>(payload_type);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetRtxSendPayloadType(payload_type) != 0) {
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetPadWithRedundantPayloads(int video_channel,
bool enable) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " pad with redundant payloads: " << (enable ? "enable" :
"disable");
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->SetPadWithRedundantPayloads(enable);
return 0;
}
int ViERTP_RTCPImpl::SetRtxReceivePayloadType(const int video_channel,
const uint8_t payload_type) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " payload_type: " << static_cast<int>(payload_type);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->SetRtxReceivePayloadType(payload_type);
return 0;
}
int ViERTP_RTCPImpl::SetStartSequenceNumber(const int video_channel,
uint16_t sequence_number) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->Sending()) {
LOG_F(LS_ERROR) << "channel " << video_channel << " is already sending.";
shared_data_->SetLastError(kViERtpRtcpAlreadySending);
return -1;
}
if (vie_channel->SetStartSequenceNumber(sequence_number) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
void ViERTP_RTCPImpl::SetRtpStateForSsrc(int video_channel,
uint32_t ssrc,
const RtpState& rtp_state) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel)
return;
if (vie_channel->Sending()) {
LOG_F(LS_ERROR) << "channel " << video_channel << " is already sending.";
return;
}
vie_channel->SetRtpStateForSsrc(ssrc, rtp_state);
}
RtpState ViERTP_RTCPImpl::GetRtpStateForSsrc(int video_channel, uint32_t ssrc) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel)
return RtpState();
return vie_channel->GetRtpStateForSsrc(ssrc);
}
int ViERTP_RTCPImpl::SetRTCPStatus(const int video_channel,
const ViERTCPMode rtcp_mode) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " mode: " << static_cast<int>(rtcp_mode);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
RTCPMethod module_mode = ViERTCPModeToRTCPMethod(rtcp_mode);
if (vie_channel->SetRTCPMode(module_mode) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetRTCPStatus(const int video_channel,
ViERTCPMode& rtcp_mode) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
RTCPMethod module_mode = kRtcpOff;
if (vie_channel->GetRTCPMode(&module_mode) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
rtcp_mode = RTCPMethodToViERTCPMode(module_mode);
return 0;
}
int ViERTP_RTCPImpl::SetRTCPCName(const int video_channel,
const char rtcp_cname[KMaxRTCPCNameLength]) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " rtcp_cname: " << rtcp_cname;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->Sending()) {
LOG_F(LS_ERROR) << "channel " << video_channel << " is already sending.";
shared_data_->SetLastError(kViERtpRtcpAlreadySending);
return -1;
}
if (vie_channel->SetRTCPCName(rtcp_cname) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetRemoteRTCPCName(
const int video_channel,
char rtcp_cname[KMaxRTCPCNameLength]) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->GetRemoteRTCPCName(rtcp_cname) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SendApplicationDefinedRTCPPacket(
const int video_channel,
const unsigned char sub_type,
unsigned int name,
const char* data,
uint16_t data_length_in_bytes) {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (!vie_channel->Sending()) {
shared_data_->SetLastError(kViERtpRtcpNotSending);
return -1;
}
RTCPMethod method;
if (vie_channel->GetRTCPMode(&method) != 0 || method == kRtcpOff) {
shared_data_->SetLastError(kViERtpRtcpRtcpDisabled);
return -1;
}
if (vie_channel->SendApplicationDefinedRTCPPacket(
sub_type, name, reinterpret_cast<const uint8_t*>(data),
data_length_in_bytes) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetNACKStatus(const int video_channel, const bool enable) {
LOG_F(LS_INFO) << "channel: " << video_channel << " "
<< (enable ? "on" : "off");
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetNACKStatus(enable) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
// Update the encoder
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (!vie_encoder) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
vie_encoder->UpdateProtectionMethod(enable);
return 0;
}
int ViERTP_RTCPImpl::SetFECStatus(const int video_channel, const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " enable: " << (enable ? "on" : "off")
<< " payload_typeRED: " << static_cast<int>(payload_typeRED)
<< " payload_typeFEC: " << static_cast<int>(payload_typeFEC);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetFECStatus(enable, payload_typeRED,
payload_typeFEC) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
// Update the encoder.
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (!vie_encoder) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
vie_encoder->UpdateProtectionMethod(false);
return 0;
}
int ViERTP_RTCPImpl::SetHybridNACKFECStatus(
const int video_channel,
const bool enable,
const unsigned char payload_typeRED,
const unsigned char payload_typeFEC) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " enable: " << (enable ? "on" : "off")
<< " payload_typeRED: " << static_cast<int>(payload_typeRED)
<< " payload_typeFEC: " << static_cast<int>(payload_typeFEC);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
// Update the channel status with hybrid NACK FEC mode.
if (vie_channel->SetHybridNACKFECStatus(enable, payload_typeRED,
payload_typeFEC) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
// Update the encoder.
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (!vie_encoder) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
vie_encoder->UpdateProtectionMethod(enable);
return 0;
}
int ViERTP_RTCPImpl::SetSenderBufferingMode(int video_channel,
int target_delay_ms) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " target_delay_ms: " << target_delay_ms;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (!vie_encoder) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
// Update the channel with buffering mode settings.
if (vie_channel->SetSenderBufferingMode(target_delay_ms) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
// Update the encoder's buffering mode settings.
vie_encoder->SetSenderBufferingMode(target_delay_ms);
return 0;
}
int ViERTP_RTCPImpl::SetReceiverBufferingMode(int video_channel,
int target_delay_ms) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " target_delay_ms: " << target_delay_ms;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
// Update the channel with buffering mode settings.
if (vie_channel->SetReceiverBufferingMode(target_delay_ms) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetKeyFrameRequestMethod(
const int video_channel,
const ViEKeyFrameRequestMethod method) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " method: " << static_cast<int>(method);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
KeyFrameRequestMethod module_method = APIRequestToModuleRequest(method);
if (vie_channel->SetKeyFrameRequestMethod(module_method) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetTMMBRStatus(const int video_channel,
const bool enable) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< "enable: " << (enable ? "on" : "off");
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->EnableTMMBR(enable) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetRembStatus(int video_channel,
bool sender,
bool receiver) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " sender: " << (sender ? "on" : "off")
<< " receiver: " << (receiver ? "on" : "off");
if (!shared_data_->channel_manager()->SetRembStatus(video_channel, sender,
receiver)) {
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetSendTimestampOffsetStatus(int video_channel,
bool enable,
int id) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< "enable: " << (enable ? "on" : "off") << " id: " << id;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetSendTimestampOffsetStatus(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetReceiveTimestampOffsetStatus(int video_channel,
bool enable,
int id) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< "enable: " << (enable ? "on" : "off") << " id: " << id;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetReceiveTimestampOffsetStatus(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetSendAbsoluteSendTimeStatus(int video_channel,
bool enable,
int id) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< "enable: " << (enable ? "on" : "off") << " id: " << id;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetSendAbsoluteSendTimeStatus(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(int video_channel,
bool enable,
int id) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< "enable: " << (enable ? "on" : "off") << " id: " << id;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetReceiveAbsoluteSendTimeStatus(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetRtcpXrRrtrStatus(int video_channel, bool enable) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " enable: " << (enable ? "on" : "off");
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->SetRtcpXrRrtrStatus(enable);
return 0;
}
int ViERTP_RTCPImpl::SetTransmissionSmoothingStatus(int video_channel,
bool enable) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " enable: " << (enable ? "on" : "off");
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->SetTransmissionSmoothingStatus(enable);
return 0;
}
int ViERTP_RTCPImpl::SetMinTransmitBitrate(int video_channel,
int min_transmit_bitrate_kbps) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " min_transmit_bitrate_kbps: " << min_transmit_bitrate_kbps;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (vie_encoder == NULL)
return -1;
vie_encoder->SetMinTransmitBitrate(min_transmit_bitrate_kbps);
return 0;
}
int ViERTP_RTCPImpl::SetReservedTransmitBitrate(
int video_channel, unsigned int reserved_transmit_bitrate_bps) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " reserved_transmit_bitrate_bps: "
<< reserved_transmit_bitrate_bps;
if (!shared_data_->channel_manager()->SetReservedTransmitBitrate(
video_channel, reserved_transmit_bitrate_bps)) {
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetReceiveChannelRtcpStatistics(
const int video_channel,
RtcpStatistics& basic_stats,
int& rtt_ms) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
// TODO(sprang): Clean this up when stats struct is propagated all the way.
uint16_t frac_lost;
if (vie_channel->GetReceivedRtcpStatistics(
&frac_lost,
&basic_stats.cumulative_lost,
&basic_stats.extended_max_sequence_number,
&basic_stats.jitter,
&rtt_ms) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
basic_stats.fraction_lost = frac_lost;
return 0;
}
int ViERTP_RTCPImpl::GetSendChannelRtcpStatistics(const int video_channel,
RtcpStatistics& basic_stats,
int& rtt_ms) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
// TODO(sprang): Clean this up when stats struct is propagated all the way.
uint16_t frac_lost;
if (vie_channel->GetSendRtcpStatistics(
&frac_lost,
&basic_stats.cumulative_lost,
&basic_stats.extended_max_sequence_number,
&basic_stats.jitter,
&rtt_ms) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
basic_stats.fraction_lost = frac_lost;
return 0;
}
int ViERTP_RTCPImpl::GetRtpStatistics(const int video_channel,
StreamDataCounters& sent,
StreamDataCounters& received) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->GetRtpStatistics(&sent.bytes,
&sent.packets,
&received.bytes,
&received.packets) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetRtcpPacketTypeCounters(
int video_channel,
RtcpPacketTypeCounter* packets_sent,
RtcpPacketTypeCounter* packets_received) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->GetRtcpPacketTypeCounters(packets_sent, packets_received);
return 0;
}
int ViERTP_RTCPImpl::GetBandwidthUsage(const int video_channel,
unsigned int& total_bitrate_sent,
unsigned int& video_bitrate_sent,
unsigned int& fec_bitrate_sent,
unsigned int& nackBitrateSent) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->GetBandwidthUsage(&total_bitrate_sent,
&video_bitrate_sent,
&fec_bitrate_sent,
&nackBitrateSent);
return 0;
}
int ViERTP_RTCPImpl::GetEstimatedSendBandwidth(
const int video_channel,
unsigned int* estimated_bandwidth) const {
if (!shared_data_->channel_manager()->GetEstimatedSendBandwidth(
video_channel, estimated_bandwidth)) {
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetEstimatedReceiveBandwidth(
const int video_channel,
unsigned int* estimated_bandwidth) const {
if (!shared_data_->channel_manager()->GetEstimatedReceiveBandwidth(
video_channel, estimated_bandwidth)) {
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetReceiveBandwidthEstimatorStats(
const int video_channel,
ReceiveBandwidthEstimatorStats* output) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->GetReceiveBandwidthEstimatorStats(output);
return 0;
}
int ViERTP_RTCPImpl::GetPacerQueuingDelayMs(
const int video_channel, int* delay_ms) const {
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (!vie_encoder) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
*delay_ms = vie_encoder->PacerQueuingDelayMs();
return 0;
}
int ViERTP_RTCPImpl::StartRTPDump(const int video_channel,
const char file_nameUTF8[1024],
RTPDirections direction) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " filename: " << file_nameUTF8
<< " direction: " << static_cast<int>(direction);
assert(FileWrapper::kMaxFileNameSize == 1024);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->StartRTPDump(file_nameUTF8, direction) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::StopRTPDump(const int video_channel,
RTPDirections direction) {
LOG_F(LS_INFO) << "channel: " << video_channel
<< " direction: " << static_cast<int>(direction);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->StopRTPDump(direction) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::RegisterRTPObserver(const int video_channel,
ViERTPObserver& observer) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->RegisterRtpObserver(&observer) != 0) {
shared_data_->SetLastError(kViERtpRtcpObserverAlreadyRegistered);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::DeregisterRTPObserver(const int video_channel) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->RegisterRtpObserver(NULL) != 0) {
shared_data_->SetLastError(kViERtpRtcpObserverNotRegistered);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::RegisterRTCPObserver(const int video_channel,
ViERTCPObserver& observer) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->RegisterRtcpObserver(&observer) != 0) {
shared_data_->SetLastError(kViERtpRtcpObserverAlreadyRegistered);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::DeregisterRTCPObserver(const int video_channel) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->RegisterRtcpObserver(NULL) != 0) {
shared_data_->SetLastError(kViERtpRtcpObserverNotRegistered);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::RegisterSendChannelRtcpStatisticsCallback(
int video_channel, RtcpStatisticsCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->RegisterSendChannelRtcpStatisticsCallback(callback);
return 0;
}
int ViERTP_RTCPImpl::DeregisterSendChannelRtcpStatisticsCallback(
int video_channel, RtcpStatisticsCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->RegisterSendChannelRtcpStatisticsCallback(NULL);
return 0;
}
int ViERTP_RTCPImpl::RegisterReceiveChannelRtcpStatisticsCallback(
const int video_channel,
RtcpStatisticsCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterReceiveChannelRtcpStatisticsCallback(callback);
return 0;
}
int ViERTP_RTCPImpl::DeregisterReceiveChannelRtcpStatisticsCallback(
const int video_channel,
RtcpStatisticsCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterReceiveChannelRtcpStatisticsCallback(NULL);
return 0;
}
int ViERTP_RTCPImpl::RegisterSendChannelRtpStatisticsCallback(
int video_channel, StreamDataCountersCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterSendChannelRtpStatisticsCallback(callback);
return 0;
}
int ViERTP_RTCPImpl::DeregisterSendChannelRtpStatisticsCallback(
int video_channel, StreamDataCountersCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterSendChannelRtpStatisticsCallback(NULL);
return 0;
}
int ViERTP_RTCPImpl::RegisterReceiveChannelRtpStatisticsCallback(
const int video_channel,
StreamDataCountersCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterReceiveChannelRtpStatisticsCallback(callback);
return 0;
}
int ViERTP_RTCPImpl::DeregisterReceiveChannelRtpStatisticsCallback(
const int video_channel,
StreamDataCountersCallback* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterReceiveChannelRtpStatisticsCallback(NULL);
return 0;
}
// Called whenever the send bitrate is updated.
int ViERTP_RTCPImpl::RegisterSendBitrateObserver(
const int video_channel,
BitrateStatisticsObserver* observer) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterSendBitrateObserver(observer);
return 0;
}
int ViERTP_RTCPImpl::DeregisterSendBitrateObserver(
const int video_channel,
BitrateStatisticsObserver* observer) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
assert(vie_channel != NULL);
vie_channel->RegisterSendBitrateObserver(NULL);
return 0;
}
int ViERTP_RTCPImpl::RegisterSendFrameCountObserver(
int video_channel, FrameCountObserver* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->RegisterSendFrameCountObserver(callback);
return 0;
}
int ViERTP_RTCPImpl::DeregisterSendFrameCountObserver(
int video_channel, FrameCountObserver* callback) {
LOG_F(LS_INFO) << "channel " << video_channel;
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->RegisterSendFrameCountObserver(NULL);
return 0;
}
} // namespace webrtc