| /* |
| * 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::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 |