1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 239e9659fc6a70f9416205c942d21deea060a8997leozwang@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 117623ce4aeb9130c937ba5836490cbb3a35679e79Peter Boström#include "webrtc/video/vie_receiver.h" 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 134fd5527ab1ba986e94671eacc96ad56f26d282bcmflodman@webrtc.org#include <vector> 144fd5527ab1ba986e94671eacc96ad56f26d282bcmflodman@webrtc.org 15415d2cd7454d93b3727fce9147090a24e4c3ccbaPeter Boström#include "webrtc/base/logging.h" 16f5d4cb19589f0b0a3736e4f653dc5a75b9df1cebpbos@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" 17ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/fec_receiver.h" 18ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" 19ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h" 20ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" 21ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" 22ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" 23ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" 24ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 252557b86e7648ffebc5781df9f093ca5a84efc219Henrik Kjellander#include "webrtc/modules/video_coding/include/video_coding.h" 2698f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h" 2798f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/metrics.h" 2898f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/tick_util.h" 2998f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/timestamp_extrapolator.h" 3098f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/trace.h" 31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc { 33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 34eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.orgstatic const int kPacketLogIntervalMs = 10000; 35eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org 36ac547a653862744d0aae560713f8418ad2852085Peter BoströmViEReceiver::ViEReceiver(VideoCodingModule* module_vcm, 37822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org RemoteBitrateEstimator* remote_bitrate_estimator, 38822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org RtpFeedback* rtp_feedback) 39d32c44738a034977b659bb4a2e76a97f027555e4mflodman@webrtc.org : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()), 40eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org clock_(Clock::GetRealTimeClock()), 41a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org rtp_header_parser_(RtpHeaderParser::Create()), 42eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org rtp_payload_registry_( 43eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))), 44eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org rtp_receiver_( 45ac547a653862744d0aae560713f8418ad2852085Peter Boström RtpReceiver::CreateVideoReceiver(clock_, 46eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org this, 47eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org rtp_feedback, 48eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org rtp_payload_registry_.get())), 49eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org rtp_receive_statistics_(ReceiveStatistics::Create(clock_)), 50dc80bae2a62a1bdbe0d342b3260a7e5b2cb958dfandresp@webrtc.org fec_receiver_(FecReceiver::Create(this)), 512853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org rtp_rtcp_(NULL), 52ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org vcm_(module_vcm), 53976a7e61c17047fdc27401a015a1be55749cc914stefan@webrtc.org remote_bitrate_estimator_(remote_bitrate_estimator), 54eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org ntp_estimator_(new RemoteNtpTimeEstimator(clock_)), 557bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receiving_(false), 563fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org restored_packet_in_use_(false), 57eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org receiving_ast_enabled_(false), 58fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org receiving_cvo_enabled_(false), 59867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang receiving_tsn_enabled_(false), 60eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org last_packet_log_ms_(-1) { 61976a7e61c17047fdc27401a015a1be55749cc914stefan@webrtc.org assert(remote_bitrate_estimator); 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 64ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.orgViEReceiver::~ViEReceiver() { 650800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org UpdateHistograms(); 66470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 67470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 680800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.orgvoid ViEReceiver::UpdateHistograms() { 690800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org FecPacketCounter counter = fec_receiver_->GetPacketCounter(); 700800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org if (counter.num_packets > 0) { 7153805324c0fa904d796cc0b333868c591f2c5f2casapersson RTC_HISTOGRAM_PERCENTAGE_SPARSE( 72ae37abbf6aa6a660e89256cc86143d6143a0139dPeter Boström "WebRTC.Video.ReceivedFecPacketsInPercent", 73ae37abbf6aa6a660e89256cc86143d6143a0139dPeter Boström static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets)); 740800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org } 750800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org if (counter.num_fec_packets > 0) { 7653805324c0fa904d796cc0b333868c591f2c5f2casapersson RTC_HISTOGRAM_PERCENTAGE_SPARSE( 7753805324c0fa904d796cc0b333868c591f2c5f2casapersson "WebRTC.Video.RecoveredMediaPacketsInPercentOfFec", 7853805324c0fa904d796cc0b333868c591f2c5f2casapersson static_cast<int>(counter.num_recovered_packets * 100 / 7953805324c0fa904d796cc0b333868c591f2c5f2casapersson counter.num_fec_packets)); 800800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org } 810800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org} 820800db74b991dec8ef750c428eb611360a1286f4asapersson@webrtc.org 83822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgbool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) { 84822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org int8_t old_pltype = -1; 85822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName, 86822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org kVideoPayloadTypeFrequency, 87822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 0, 88822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org video_codec.maxBitrate, 89822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &old_pltype) != -1) { 90822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_->DeRegisterReceivePayload(old_pltype); 91822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 92822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 93822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return RegisterPayload(video_codec); 94822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 95822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 96822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgbool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) { 97822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return rtp_receiver_->RegisterReceivePayload(video_codec.plName, 98822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org video_codec.plType, 99822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org kVideoPayloadTypeFrequency, 100822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 0, 101822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org video_codec.maxBitrate) == 0; 102822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 103822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 1047bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgvoid ViEReceiver::SetNackStatus(bool enable, 105822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org int max_nack_reordering_threshold) { 1067bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!enable) { 1077bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Reset the threshold back to the lower default threshold when NACK is 1087bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // disabled since we no longer will be receiving retransmissions. 1097bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org max_nack_reordering_threshold = kDefaultMaxReorderingThreshold; 1107bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 1117bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->SetMaxReorderingThreshold( 1127bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org max_nack_reordering_threshold); 1137bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); 114822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 115822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 116e62202fedf57b74cc263246c0586ee353978caf8Shao Changbinvoid ViEReceiver::SetRtxPayloadType(int payload_type, 117e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin int associated_payload_type) { 118e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin rtp_payload_registry_->SetRtxPayloadType(payload_type, 119e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin associated_payload_type); 120822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 121822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 12265220a70a38ffe252b587775c5e9104606ab7c2cnoahricvoid ViEReceiver::SetUseRtxPayloadMappingOnRestore(bool val) { 12365220a70a38ffe252b587775c5e9104606ab7c2cnoahric rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(val); 12465220a70a38ffe252b587775c5e9104606ab7c2cnoahric} 12565220a70a38ffe252b587775c5e9104606ab7c2cnoahric 126ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.orgvoid ViEReceiver::SetRtxSsrc(uint32_t ssrc) { 127ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.org rtp_payload_registry_->SetRtxSsrc(ssrc); 128822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 129822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 130d952c40c7e31c1603988c1f09ebfba9f17c6a866asapersson@webrtc.orgbool ViEReceiver::GetRtxSsrc(uint32_t* ssrc) const { 131d952c40c7e31c1603988c1f09ebfba9f17c6a866asapersson@webrtc.org return rtp_payload_registry_->GetRtxSsrc(ssrc); 132d952c40c7e31c1603988c1f09ebfba9f17c6a866asapersson@webrtc.org} 133d952c40c7e31c1603988c1f09ebfba9f17c6a866asapersson@webrtc.org 134273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.orgbool ViEReceiver::IsFecEnabled() const { 135273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org return rtp_payload_registry_->ulpfec_payload_type() > -1; 136273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org} 137273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org 138822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orguint32_t ViEReceiver::GetRemoteSsrc() const { 139822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return rtp_receiver_->SSRC(); 140822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 141822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 142822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgint ViEReceiver::GetCsrcs(uint32_t* csrcs) const { 143822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return rtp_receiver_->CSRCs(csrcs); 144822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 145822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 1462853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.orgvoid ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) { 1472853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org rtp_rtcp_ = module; 1482853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org} 1492853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 150822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgRtpReceiver* ViEReceiver::GetRtpReceiver() const { 151822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return rtp_receiver_.get(); 152822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 153822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 154d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boströmvoid ViEReceiver::RegisterRtpRtcpModules( 155d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström const std::vector<RtpRtcp*>& rtp_modules) { 1566cff9cf8a3562f76b1dfe4584f447dd66c2d05f2Peter Boström CriticalSectionScoped cs(receive_cs_.get()); 157d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström // Only change the "simulcast" modules, the base module can be accessed 158d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström // without a lock whereas the simulcast modules require locking as they can be 159d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström // changed in runtime. 160d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström rtp_rtcp_simulcast_ = 161d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström std::vector<RtpRtcp*>(rtp_modules.begin() + 1, rtp_modules.end()); 1626cff9cf8a3562f76b1dfe4584f447dd66c2d05f2Peter Boström} 1636cff9cf8a3562f76b1dfe4584f447dd66c2d05f2Peter Boström 16408994cc525110d7cef1e3990aef7f2d6fa0a8f2cstefan@webrtc.orgbool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) { 165a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org if (enable) { 166a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org return rtp_header_parser_->RegisterRtpHeaderExtension( 167a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org kRtpExtensionTransmissionTimeOffset, id); 168a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } else { 169a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org return rtp_header_parser_->DeregisterRtpHeaderExtension( 170a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org kRtpExtensionTransmissionTimeOffset); 171a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } 172a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org} 173a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org 17408994cc525110d7cef1e3990aef7f2d6fa0a8f2cstefan@webrtc.orgbool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { 175a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org if (enable) { 1763fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org if (rtp_header_parser_->RegisterRtpHeaderExtension( 1773fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org kRtpExtensionAbsoluteSendTime, id)) { 1783fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org receiving_ast_enabled_ = true; 1793fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org return true; 1803fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org } else { 1813fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org return false; 1823fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org } 183a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } else { 1843fb8f7bbb0c5e074d0744c57905c5f49bb7d8304solenberg@webrtc.org receiving_ast_enabled_ = false; 185a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org return rtp_header_parser_->DeregisterRtpHeaderExtension( 186a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org kRtpExtensionAbsoluteSendTime); 187a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } 188a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org} 189a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org 190fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.orgbool ViEReceiver::SetReceiveVideoRotationStatus(bool enable, int id) { 191fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org if (enable) { 192fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org if (rtp_header_parser_->RegisterRtpHeaderExtension( 193fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org kRtpExtensionVideoRotation, id)) { 194fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org receiving_cvo_enabled_ = true; 195fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org return true; 196fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org } else { 197fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org return false; 198fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org } 199fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org } else { 200fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org receiving_cvo_enabled_ = false; 201fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org return rtp_header_parser_->DeregisterRtpHeaderExtension( 202fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org kRtpExtensionVideoRotation); 203fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org } 204fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org} 205fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org 206867fb5224e1ba6a1c2cd523c005499a93ed61a08sprangbool ViEReceiver::SetReceiveTransportSequenceNumber(bool enable, int id) { 207867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang if (enable) { 208867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang if (rtp_header_parser_->RegisterRtpHeaderExtension( 209867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang kRtpExtensionTransportSequenceNumber, id)) { 210867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang receiving_tsn_enabled_ = true; 211867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang return true; 212867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang } else { 213867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang return false; 214867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang } 215867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang } else { 216867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang receiving_tsn_enabled_ = false; 217867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang return rtp_header_parser_->DeregisterRtpHeaderExtension( 218867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang kRtpExtensionTransportSequenceNumber); 219867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang } 220867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang} 221867fb5224e1ba6a1c2cd523c005499a93ed61a08sprang 222ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.orgint ViEReceiver::ReceivedRTPPacket(const void* rtp_packet, 2234591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtp_packet_length, 224a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org const PacketTime& packet_time) { 225fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.org return InsertRTPPacket(static_cast<const uint8_t*>(rtp_packet), 226a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org rtp_packet_length, packet_time); 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 229ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.orgint ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet, 2304591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtcp_packet_length) { 231fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.org return InsertRTCPPacket(static_cast<const uint8_t*>(rtcp_packet), 232ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org rtcp_packet_length); 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2354591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgint32_t ViEReceiver::OnReceivedPayloadData(const uint8_t* payload_data, 2364591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org const size_t payload_size, 2374591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org const WebRtcRTPHeader* rtp_header) { 238cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; 23988abf11cadc0eb8986561a942ecc13ad9a324f16wu@webrtc.org rtp_header_with_ntp.ntp_time_ms = 24088abf11cadc0eb8986561a942ecc13ad9a324f16wu@webrtc.org ntp_estimator_->Estimate(rtp_header->header.timestamp); 241cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org if (vcm_->IncomingPacket(payload_data, 242cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org payload_size, 243cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org rtp_header_with_ntp) != 0) { 244ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org // Check this... 245ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org return -1; 246ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org } 247ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org return 0; 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 250822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgbool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, 2514591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtp_packet_length) { 252822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org RTPHeader header; 253822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) { 254822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return false; 255822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 256822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org header.payload_type_frequency = kVideoPayloadTypeFrequency; 25701581da71145d4b9504d12cfad0c988d1fc68654stefan@webrtc.org bool in_order = IsPacketInOrder(header); 25801581da71145d4b9504d12cfad0c988d1fc68654stefan@webrtc.org return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); 259822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 260822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 261fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.orgint ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet, 2624591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtp_packet_length, 263a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org const PacketTime& packet_time) { 264ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org { 265d32c44738a034977b659bb4a2e76a97f027555e4mflodman@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 266b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org if (!receiving_) { 267b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org return -1; 268b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org } 269ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org } 270fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.org 271a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org RTPHeader header; 272fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.org if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, 273a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org &header)) { 274a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org return -1; 275a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } 2764591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payload_length = rtp_packet_length - header.headerLength; 277a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org int64_t arrival_time_ms; 278eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org int64_t now_ms = clock_->TimeInMilliseconds(); 279a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org if (packet_time.timestamp != -1) 280a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org arrival_time_ms = (packet_time.timestamp + 500) / 1000; 281a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org else 282eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org arrival_time_ms = now_ms; 283eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org 284eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org { 285eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org // Periodically log the RTP header of incoming packets. 286eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 287eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { 288eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org std::stringstream ss; 289eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org ss << "Packet received on SSRC: " << header.ssrc << " with payload type: " 290eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org << static_cast<int>(header.payloadType) << ", timestamp: " 291eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org << header.timestamp << ", sequence number: " << header.sequenceNumber 292eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org << ", arrival time: " << arrival_time_ms; 293eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org if (header.extension.hasTransmissionTimeOffset) 294eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org ss << ", toffset: " << header.extension.transmissionTimeOffset; 295eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org if (header.extension.hasAbsoluteSendTime) 296eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org ss << ", abs send time: " << header.extension.absoluteSendTime; 297eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org LOG(LS_INFO) << ss.str(); 298eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org last_packet_log_ms_ = now_ms; 299eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org } 300eb24b04f1631aeee670230aa6600d28ae23890d0stefan@webrtc.org } 301a9890800e078105f21f0a21358ee59a0b3736af6wu@webrtc.org 302ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_length, 303ff4ea9310e981da6292fb044cff9eeefd986cf2bStefan Holmer header, true); 304822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org header.payload_type_frequency = kVideoPayloadTypeFrequency; 3057bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 30648df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org bool in_order = IsPacketInOrder(header); 3077bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_payload_registry_->SetIncomingPayloadType(header); 3081457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order) 309fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.org ? 0 310fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.org : -1; 3111457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org // Update receive statistics after ReceivePacket. 3121457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org // Receive statistics will be reset if the payload type changes (make sure 3131457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org // that the first packet is included in the stats). 3141457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org rtp_receive_statistics_->IncomingPacket( 3151457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org header, rtp_packet_length, IsPacketRetransmitted(header, in_order)); 3161457b4737a82cc3624daf3a997f6257d13a3f974asapersson@webrtc.org return ret; 3177bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 3187bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 3197bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool ViEReceiver::ReceivePacket(const uint8_t* packet, 3204591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t packet_length, 3217bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const RTPHeader& header, 3227bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org bool in_order) { 3237bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (rtp_payload_registry_->IsEncapsulated(header)) { 3247bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return ParseAndHandleEncapsulatingHeader(packet, packet_length, header); 3257bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 3267bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const uint8_t* payload = packet + header.headerLength; 3274591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org assert(packet_length >= header.headerLength); 3284591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payload_length = packet_length - header.headerLength; 329822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org PayloadUnion payload_specific; 330822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 331822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &payload_specific)) { 3327bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 333822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 3347bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, 3357bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org payload_specific, in_order); 3367bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 3377bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 3387bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet, 3394591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t packet_length, 3407bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const RTPHeader& header) { 3417bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (rtp_payload_registry_->IsRed(header)) { 3420e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type(); 34337c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org if (packet[header.headerLength] == ulpfec_pt) { 344273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org rtp_receive_statistics_->FecPacketReceived(header, packet_length); 34537c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org // Notify vcm about received FEC packets to avoid NACKing these packets. 34637c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org NotifyReceiverOfFecPacket(header); 34737c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org } 3487bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (fec_receiver_->AddReceivedRedPacket( 3490e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header, packet, packet_length, ulpfec_pt) != 0) { 3507bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 3517bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 3527bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return fec_receiver_->ProcessReceivedFec() == 0; 3537bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } else if (rtp_payload_registry_->IsRtx(header)) { 3547c6ff2da261699628e7253d9d10068bc531fe0f8stefan@webrtc.org if (header.headerLength + header.paddingLength == packet_length) { 3557c6ff2da261699628e7253d9d10068bc531fe0f8stefan@webrtc.org // This is an empty packet and should be silently dropped before trying to 3567c6ff2da261699628e7253d9d10068bc531fe0f8stefan@webrtc.org // parse the RTX header. 3577c6ff2da261699628e7253d9d10068bc531fe0f8stefan@webrtc.org return true; 3587c6ff2da261699628e7253d9d10068bc531fe0f8stefan@webrtc.org } 3597bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Remove the RTX header and parse the original RTP header. 3607bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (packet_length < header.headerLength) 3617bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 3624591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org if (packet_length > sizeof(restored_packet_)) 3637bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 3647bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 3657bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (restored_packet_in_use_) { 3664e2806d85fb1a526732ba4c046cbc935bc47bf1apbos@webrtc.org LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet."; 3677bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 3687bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 3697bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_payload_registry_->RestoreOriginalPacket( 37065220a70a38ffe252b587775c5e9104606ab7c2cnoahric restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(), 37165220a70a38ffe252b587775c5e9104606ab7c2cnoahric header)) { 3724e2806d85fb1a526732ba4c046cbc935bc47bf1apbos@webrtc.org LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header"; 3737bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 3747bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 3757bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org restored_packet_in_use_ = true; 37665220a70a38ffe252b587775c5e9104606ab7c2cnoahric bool ret = OnRecoveredPacket(restored_packet_, packet_length); 3777bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org restored_packet_in_use_ = false; 3787bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return ret; 3797bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 3807bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 38337c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.orgvoid ViEReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) { 38437c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org int8_t last_media_payload_type = 38537c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org rtp_payload_registry_->last_received_media_payload_type(); 38637c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org if (last_media_payload_type < 0) { 38737c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org LOG(LS_WARNING) << "Failed to get last media payload type."; 38837c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org return; 38937c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org } 39037c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org // Fake an empty media packet. 39137c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org WebRtcRTPHeader rtp_header = {}; 39237c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org rtp_header.header = header; 39337c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org rtp_header.header.payloadType = last_media_payload_type; 39437c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org rtp_header.header.paddingLength = 0; 39537c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org PayloadUnion payload_specific; 39637c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org if (!rtp_payload_registry_->GetPayloadSpecifics(last_media_payload_type, 39737c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org &payload_specific)) { 39837c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org LOG(LS_WARNING) << "Failed to get payload specifics."; 39937c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org return; 40037c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org } 40137c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org rtp_header.type.Video.codec = payload_specific.Video.videoCodecType; 402fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org rtp_header.type.Video.rotation = kVideoRotation_0; 403fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org if (header.extension.hasVideoRotation) { 404fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org rtp_header.type.Video.rotation = 405fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org ConvertCVOByteToVideoRotation(header.extension.videoRotation); 406fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org } 40737c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org OnReceivedPayloadData(NULL, 0, &rtp_header); 40837c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org} 40937c0559c1edd108b345abcce1939f9b8d78d02a3asapersson@webrtc.org 410fc320466d12e16c1e80f57b8cff864627f2766f6solenberg@webrtc.orgint ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet, 4114591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtcp_packet_length) { 412ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org { 413d32c44738a034977b659bb4a2e76a97f027555e4mflodman@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 414b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org if (!receiving_) { 415b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org return -1; 416b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org } 417ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org 418d6f1a38165455d743fbe61f6980f22be6a3c4de9Peter Boström for (RtpRtcp* rtp_rtcp : rtp_rtcp_simulcast_) 4196cff9cf8a3562f76b1dfe4584f447dd66c2d05f2Peter Boström rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 420ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org } 4212853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org assert(rtp_rtcp_); // Should be set by owner at construction time. 422cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length); 423cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org if (ret != 0) { 424cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org return ret; 425cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org } 426cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org 42716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t rtt = 0; 4282c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, NULL, NULL, NULL); 4292c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org if (rtt == 0) { 4302c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org // Waiting for valid rtt. 4312c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org return 0; 4322c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org } 4332c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org uint32_t ntp_secs = 0; 4342c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org uint32_t ntp_frac = 0; 4352c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org uint32_t rtp_timestamp = 0; 4362c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org if (0 != rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, 4372c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org &rtp_timestamp)) { 4382c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org // Waiting for RTCP. 4392c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org return 0; 4402c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org } 4412c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org ntp_estimator_->UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); 442cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org 443cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org return 0; 444cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org} 445cd70119a106e42ab7eac58050d067bc050610739wu@webrtc.org 446ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.orgvoid ViEReceiver::StartReceive() { 447b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 448ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org receiving_ = true; 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 451ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.orgvoid ViEReceiver::StopReceive() { 452b6433b7a1e0771aea3701279f6745543070b0589braveyao@webrtc.org CriticalSectionScoped cs(receive_cs_.get()); 453ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org receiving_ = false; 454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 456822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgReceiveStatistics* ViEReceiver::GetReceiveStatistics() const { 457822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return rtp_receive_statistics_.get(); 458822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 459822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 4607bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const { 4617bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org StreamStatistician* statistician = 4627bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 4637bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!statistician) 4647bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4657bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return statistician->IsPacketInOrder(header.sequenceNumber); 4667bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 4677bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 46848df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.orgbool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header, 46948df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org bool in_order) const { 4707bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Retransmissions are handled separately if RTX is enabled. 4717bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (rtp_payload_registry_->RtxEnabled()) 4727bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4737bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org StreamStatistician* statistician = 4747bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 4757bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!statistician) 4767bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4777bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Check if this is a retransmission. 47816825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t min_rtt = 0; 4797bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); 48048df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org return !in_order && 4817bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org statistician->IsRetransmitOfOldPacket(header, min_rtt); 482822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 483ad4ee3659e4298d9b006d00399e9a77e18d2eae1mflodman@webrtc.org} // namespace webrtc 484