1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_receiver.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13cd1ac8b77e14f5f84a0d99f732b0aff7297baa4cmflodman@webrtc.org#include <vector> 14cd1ac8b77e14f5f84a0d99f732b0aff7297baa4cmflodman@webrtc.org 15281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" 16db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h" 177fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" 182fae0d1b007dd3689fd002f31391dab6f1cd6628wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h" 196696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 207fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 217fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" 22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/utility/interface/rtp_dump.h" 24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h" 25281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 26093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 27281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h" 28d2fb259b3bc61c68f368929510215a7ee7d00fdawu@webrtc.org#include "webrtc/system_wrappers/interface/timestamp_extrapolator.h" 292fae0d1b007dd3689fd002f31391dab6f1cd6628wu@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViEReceiver::ViEReceiver(const int32_t channel_id, 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoCodingModule* module_vcm, 357fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org RemoteBitrateEstimator* remote_bitrate_estimator, 367fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org RtpFeedback* rtp_feedback) 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()), 386696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org rtp_header_parser_(RtpHeaderParser::Create()), 397fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_payload_registry_(new RTPPayloadRegistry( 4099681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org RTPPayloadStrategy::CreateStrategy(false))), 417fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_receiver_(RtpReceiver::CreateVideoReceiver( 427fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org channel_id, Clock::GetRealTimeClock(), this, rtp_feedback, 437fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_payload_registry_.get())), 447fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_receive_statistics_(ReceiveStatistics::Create( 457fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org Clock::GetRealTimeClock())), 4699681317b0a9dc29c1682a17908f382eac16bd2aandresp@webrtc.org fec_receiver_(FecReceiver::Create(this)), 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_rtcp_(NULL), 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_(module_vcm), 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org remote_bitrate_estimator_(remote_bitrate_estimator), 502fae0d1b007dd3689fd002f31391dab6f1cd6628wu@webrtc.org ntp_estimator_(new RemoteNtpTimeEstimator(Clock::GetRealTimeClock())), 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_(NULL), 52db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org receiving_(false), 532d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org restored_packet_in_use_(false), 542d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org receiving_ast_enabled_(false) { 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(remote_bitrate_estimator); 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViEReceiver::~ViEReceiver() { 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_) { 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_->Stop(); 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RtpDump::DestroyRtpDump(rtp_dump_); 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_ = NULL; 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 667fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgbool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) { 677fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int8_t old_pltype = -1; 687fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName, 697fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org kVideoPayloadTypeFrequency, 707fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 0, 717fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org video_codec.maxBitrate, 727fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org &old_pltype) != -1) { 737fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org rtp_payload_registry_->DeRegisterReceivePayload(old_pltype); 747fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org } 757fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 767fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return RegisterPayload(video_codec); 777fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 787fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 797fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgbool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) { 807fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return rtp_receiver_->RegisterReceivePayload(video_codec.plName, 817fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org video_codec.plType, 827fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org kVideoPayloadTypeFrequency, 837fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 0, 847fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org video_codec.maxBitrate) == 0; 857fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 867fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 87db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.orgvoid ViEReceiver::SetNackStatus(bool enable, 887fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int max_nack_reordering_threshold) { 89db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (!enable) { 90db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org // Reset the threshold back to the lower default threshold when NACK is 91db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org // disabled since we no longer will be receiving retransmissions. 92db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org max_nack_reordering_threshold = kDefaultMaxReorderingThreshold; 93db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } 94db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org rtp_receive_statistics_->SetMaxReorderingThreshold( 95db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org max_nack_reordering_threshold); 96db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); 977fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 987fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 99903e746cc9a73da17bfa3f6110293582fa6ee3bestefan@webrtc.orgvoid ViEReceiver::SetRtxPayloadType(int payload_type) { 100903e746cc9a73da17bfa3f6110293582fa6ee3bestefan@webrtc.org rtp_payload_registry_->SetRtxPayloadType(payload_type); 1017fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 1027fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 103903e746cc9a73da17bfa3f6110293582fa6ee3bestefan@webrtc.orgvoid ViEReceiver::SetRtxSsrc(uint32_t ssrc) { 104903e746cc9a73da17bfa3f6110293582fa6ee3bestefan@webrtc.org rtp_payload_registry_->SetRtxSsrc(ssrc); 1057fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 1067fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 1077fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orguint32_t ViEReceiver::GetRemoteSsrc() const { 1087fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return rtp_receiver_->SSRC(); 1097fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 1107fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 1117fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgint ViEReceiver::GetCsrcs(uint32_t* csrcs) const { 1127fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return rtp_receiver_->CSRCs(csrcs); 1137fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 1147fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) { 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_rtcp_ = module; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1197fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgRtpReceiver* ViEReceiver::GetRtpReceiver() const { 1207fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return rtp_receiver_.get(); 1217fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 1227fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEReceiver::RegisterSimulcastRtpRtcpModules( 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const std::list<RtpRtcp*>& rtp_modules) { 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_rtcp_simulcast_.clear(); 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!rtp_modules.empty()) { 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_rtcp_simulcast_.insert(rtp_rtcp_simulcast_.begin(), 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_modules.begin(), 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_modules.end()); 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1354e5f9831edffe845ae2474e9f7df0e5f9e35bdd5stefan@webrtc.orgbool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) { 1366696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org if (enable) { 1376696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org return rtp_header_parser_->RegisterRtpHeaderExtension( 1386696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org kRtpExtensionTransmissionTimeOffset, id); 1396696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org } else { 1406696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org return rtp_header_parser_->DeregisterRtpHeaderExtension( 1416696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org kRtpExtensionTransmissionTimeOffset); 1426696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org } 1436696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org} 1446696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org 1454e5f9831edffe845ae2474e9f7df0e5f9e35bdd5stefan@webrtc.orgbool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { 1466696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org if (enable) { 1472d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org if (rtp_header_parser_->RegisterRtpHeaderExtension( 1482d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org kRtpExtensionAbsoluteSendTime, id)) { 1492d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org receiving_ast_enabled_ = true; 1502d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org return true; 1512d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org } else { 1522d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org return false; 1532d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org } 1546696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org } else { 1552d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org receiving_ast_enabled_ = false; 1566696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org return rtp_header_parser_->DeregisterRtpHeaderExtension( 1576696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org kRtpExtensionAbsoluteSendTime); 1586696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org } 1596696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org} 1606696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEReceiver::ReceivedRTPPacket(const void* rtp_packet, 162efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org int rtp_packet_length, 163efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org const PacketTime& packet_time) { 164800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org return InsertRTPPacket(static_cast<const uint8_t*>(rtp_packet), 165efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org rtp_packet_length, packet_time); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet, 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int rtcp_packet_length) { 170800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org return InsertRTCPPacket(static_cast<const uint8_t*>(rtcp_packet), 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtcp_packet_length); 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 17467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEReceiver::OnReceivedPayloadData( 17567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint8_t* payload_data, const uint16_t payload_size, 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const WebRtcRTPHeader* rtp_header) { 177093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; 1782fae0d1b007dd3689fd002f31391dab6f1cd6628wu@webrtc.org rtp_header_with_ntp.ntp_time_ms = 1792fae0d1b007dd3689fd002f31391dab6f1cd6628wu@webrtc.org ntp_estimator_->Estimate(rtp_header->header.timestamp); 180093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org if (vcm_->IncomingPacket(payload_data, 181093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org payload_size, 182093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org rtp_header_with_ntp) != 0) { 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Check this... 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1897fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgbool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, 1907fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org int rtp_packet_length) { 1917fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org RTPHeader header; 1927fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) { 1937fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return false; 1947fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org } 1957fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org header.payload_type_frequency = kVideoPayloadTypeFrequency; 196d01c49138f5c9c49c86251094f72759ee2c4705fstefan@webrtc.org bool in_order = IsPacketInOrder(header); 197d01c49138f5c9c49c86251094f72759ee2c4705fstefan@webrtc.org return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); 1987fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 1997fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 2002d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.orgvoid ViEReceiver::ReceivedBWEPacket( 2012d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org int64_t arrival_time_ms, int payload_size, const RTPHeader& header) { 2022d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org // Only forward if the incoming packet *and* the channel are both configured 2032d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org // to receive absolute sender time. RTP time stamps may have different rates 2042d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org // for audio and video and shouldn't be mixed. 2052d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org if (header.extension.hasAbsoluteSendTime && receiving_ast_enabled_) { 2062d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size, 2072d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org header); 2082d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org } 2092d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org} 2102d3624ceb06407a4440433f816612fc150bfea42solenberg@webrtc.org 211800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.orgint ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet, 212efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org int rtp_packet_length, 213efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org const PacketTime& packet_time) { 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 216d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org if (!receiving_) { 217d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org return -1; 218d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org } 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_) { 220800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org rtp_dump_->DumpPacket(rtp_packet, 221800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org static_cast<uint16_t>(rtp_packet_length)); 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 224800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org 2256696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org RTPHeader header; 226800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, 2276696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org &header)) { 2286696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org return -1; 2296696fba9388a386f7d0e3e0d93df48d43f05cd95stefan@webrtc.org } 230800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org int payload_length = rtp_packet_length - header.headerLength; 231efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org int64_t arrival_time_ms; 232efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org if (packet_time.timestamp != -1) 233efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org arrival_time_ms = (packet_time.timestamp + 500) / 1000; 234efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org else 235efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org arrival_time_ms = TickTime::MillisecondTimestamp(); 236efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org 237efeb8ce7e183005e557a2d107203e2057cec26a8wu@webrtc.org remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, 238db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org payload_length, header); 2397fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org header.payload_type_frequency = kVideoPayloadTypeFrequency; 240db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org 2417e97e4c84dc21b2853f5158a03dcceb569e493adstefan@webrtc.org bool in_order = IsPacketInOrder(header); 242db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org rtp_payload_registry_->SetIncomingPayloadType(header); 24399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order) 244800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org ? 0 245800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org : -1; 24699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org // Update receive statistics after ReceivePacket. 24799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org // Receive statistics will be reset if the payload type changes (make sure 24899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org // that the first packet is included in the stats). 24999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org rtp_receive_statistics_->IncomingPacket( 25099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org header, rtp_packet_length, IsPacketRetransmitted(header, in_order)); 25199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org return ret; 252db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org} 253db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org 254db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.orgbool ViEReceiver::ReceivePacket(const uint8_t* packet, 255db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org int packet_length, 256db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org const RTPHeader& header, 257db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org bool in_order) { 258db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (rtp_payload_registry_->IsEncapsulated(header)) { 259db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); 260db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } 261db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org const uint8_t* payload = packet + header.headerLength; 262db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org int payload_length = packet_length - header.headerLength; 263db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org assert(payload_length >= 0); 2647fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org PayloadUnion payload_specific; 2657fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 2667fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org &payload_specific)) { 267db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 2687fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org } 269db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, 270db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org payload_specific, in_order); 271db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org} 272db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org 273db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.orgbool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet, 274db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org int packet_length, 275db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org const RTPHeader& header) { 276db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (rtp_payload_registry_->IsRed(header)) { 2777d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type(); 2787d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org if (packet[header.headerLength] == ulpfec_pt) 2797d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org rtp_receive_statistics_->FecPacketReceived(header.ssrc); 280db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (fec_receiver_->AddReceivedRedPacket( 2817d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org header, packet, packet_length, ulpfec_pt) != 0) { 282db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 283db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } 284db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return fec_receiver_->ProcessReceivedFec() == 0; 285db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } else if (rtp_payload_registry_->IsRtx(header)) { 286fbd6f47f33ba2f1f6884dbd6bb975325f6c0adc3stefan@webrtc.org if (header.headerLength + header.paddingLength == packet_length) { 287fbd6f47f33ba2f1f6884dbd6bb975325f6c0adc3stefan@webrtc.org // This is an empty packet and should be silently dropped before trying to 288fbd6f47f33ba2f1f6884dbd6bb975325f6c0adc3stefan@webrtc.org // parse the RTX header. 289fbd6f47f33ba2f1f6884dbd6bb975325f6c0adc3stefan@webrtc.org return true; 290fbd6f47f33ba2f1f6884dbd6bb975325f6c0adc3stefan@webrtc.org } 291db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org // Remove the RTX header and parse the original RTP header. 292db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (packet_length < header.headerLength) 293db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 294db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (packet_length > static_cast<int>(sizeof(restored_packet_))) 295db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 296db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 297db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (restored_packet_in_use_) { 2983468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; 299db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 300db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } 301db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org uint8_t* restored_packet_ptr = restored_packet_; 302db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (!rtp_payload_registry_->RestoreOriginalPacket( 303db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(), 304db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org header)) { 3053468f20608200e23fa0ad7435490260419cf70c5pbos@webrtc.org LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header"; 306db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 307db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } 308db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org restored_packet_in_use_ = true; 309db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length); 310db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org restored_packet_in_use_ = false; 311db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return ret; 312db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org } 313db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 316800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.orgint ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int rtcp_packet_length) { 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 320d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org if (!receiving_) { 321d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org return -1; 322d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org } 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_) { 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_->DumpPacket( 326800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org rtcp_packet, static_cast<uint16_t>(rtcp_packet_length)); 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 328800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin(); 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (it != rtp_rtcp_simulcast_.end()) { 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RtpRtcp* rtp_rtcp = *it++; 332800136d2ca86bc644a2914db8f4a11b13a21dcaasolenberg@webrtc.org rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(rtp_rtcp_); // Should be set by owner at construction time. 336093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 337093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org if (ret != 0) { 338093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org return ret; 339093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org } 340093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org 341dd0f8b2a5f7fde0d8a515ea90bcf32fcad7ad230wu@webrtc.org ntp_estimator_->UpdateRtcpTimestamp(rtp_receiver_->SSRC(), rtp_rtcp_); 342093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org 343093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org return 0; 344093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org} 345093fc0b0b0b9ca4fe56a32e17c9c418382e802f0wu@webrtc.org 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEReceiver::StartReceive() { 347d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org receiving_ = true; 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEReceiver::StopReceive() { 352d69e2f437a136a90cb1edc42a1bd498d12f5c295braveyao@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org receiving_ = false; 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) { 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_) { 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Restart it if it already exists and is started 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_->Stop(); 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_ = RtpDump::CreateRtpDump(); 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_ == NULL) { 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_->Start(file_nameUTF8) != 0) { 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RtpDump::DestroyRtpDump(rtp_dump_); 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_ = NULL; 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEReceiver::StopRTPDump() { 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_) { 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rtp_dump_->IsActive()) { 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_->Stop(); 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RtpDump::DestroyRtpDump(rtp_dump_); 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_dump_ = NULL; 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 389d1e7facca966ca4b7632940d71f62deea5094083jiayl@webrtc.orgvoid ViEReceiver::GetReceiveBandwidthEstimatorStats( 390d1e7facca966ca4b7632940d71f62deea5094083jiayl@webrtc.org ReceiveBandwidthEstimatorStats* output) const { 391d1e7facca966ca4b7632940d71f62deea5094083jiayl@webrtc.org remote_bitrate_estimator_->GetStats(output); 392d1e7facca966ca4b7632940d71f62deea5094083jiayl@webrtc.org} 393d1e7facca966ca4b7632940d71f62deea5094083jiayl@webrtc.org 3947fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { 3957fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org return rtp_receive_statistics_.get(); 3967fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 3977fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org 398db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.orgbool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { 399db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org StreamStatistician* statistician = 400db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 401db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (!statistician) 402db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 403db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return statistician->IsPacketInOrder(header.sequenceNumber); 404db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org} 405db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org 4067e97e4c84dc21b2853f5158a03dcceb569e493adstefan@webrtc.orgbool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, 4077e97e4c84dc21b2853f5158a03dcceb569e493adstefan@webrtc.org bool in_order) const { 408db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org // Retransmissions are handled separately if RTX is enabled. 409db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (rtp_payload_registry_->RtxEnabled()) 410db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 411db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org StreamStatistician* statistician = 412db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 413db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org if (!statistician) 414db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org return false; 415db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org // Check if this is a retransmission. 416db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org uint16_t min_rtt = 0; 417db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); 4187e97e4c84dc21b2853f5158a03dcceb569e493adstefan@webrtc.org return !in_order && 419db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org statistician->IsRetransmitOfOldPacket(header, min_rtt); 4207fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org} 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 422