1 /* 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/video/payload_router.h" 12 13 #include "webrtc/base/checks.h" 14 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" 15 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 16 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 17 18 namespace webrtc { 19 20 PayloadRouter::PayloadRouter() 21 : crit_(CriticalSectionWrapper::CreateCriticalSection()), 22 active_(false) {} 23 24 PayloadRouter::~PayloadRouter() {} 25 26 size_t PayloadRouter::DefaultMaxPayloadLength() { 27 const size_t kIpUdpSrtpLength = 44; 28 return IP_PACKET_SIZE - kIpUdpSrtpLength; 29 } 30 31 void PayloadRouter::SetSendingRtpModules( 32 const std::list<RtpRtcp*>& rtp_modules) { 33 CriticalSectionScoped cs(crit_.get()); 34 rtp_modules_.clear(); 35 rtp_modules_.reserve(rtp_modules.size()); 36 for (auto* rtp_module : rtp_modules) { 37 rtp_modules_.push_back(rtp_module); 38 } 39 } 40 41 void PayloadRouter::set_active(bool active) { 42 CriticalSectionScoped cs(crit_.get()); 43 active_ = active; 44 } 45 46 bool PayloadRouter::active() { 47 CriticalSectionScoped cs(crit_.get()); 48 return active_ && !rtp_modules_.empty(); 49 } 50 51 bool PayloadRouter::RoutePayload(FrameType frame_type, 52 int8_t payload_type, 53 uint32_t time_stamp, 54 int64_t capture_time_ms, 55 const uint8_t* payload_data, 56 size_t payload_length, 57 const RTPFragmentationHeader* fragmentation, 58 const RTPVideoHeader* rtp_video_hdr) { 59 CriticalSectionScoped cs(crit_.get()); 60 if (!active_ || rtp_modules_.empty()) 61 return false; 62 63 // The simulcast index might actually be larger than the number of modules in 64 // case the encoder was processing a frame during a codec reconfig. 65 if (rtp_video_hdr != NULL && 66 rtp_video_hdr->simulcastIdx >= rtp_modules_.size()) 67 return false; 68 69 int stream_idx = 0; 70 if (rtp_video_hdr != NULL) 71 stream_idx = rtp_video_hdr->simulcastIdx; 72 return rtp_modules_[stream_idx]->SendOutgoingData( 73 frame_type, payload_type, time_stamp, capture_time_ms, payload_data, 74 payload_length, fragmentation, rtp_video_hdr) == 0 ? true : false; 75 } 76 77 void PayloadRouter::SetTargetSendBitrates( 78 const std::vector<uint32_t>& stream_bitrates) { 79 CriticalSectionScoped cs(crit_.get()); 80 if (stream_bitrates.size() < rtp_modules_.size()) { 81 // There can be a size mis-match during codec reconfiguration. 82 return; 83 } 84 int idx = 0; 85 for (auto* rtp_module : rtp_modules_) { 86 rtp_module->SetTargetSendBitrate(stream_bitrates[idx++]); 87 } 88 } 89 90 size_t PayloadRouter::MaxPayloadLength() const { 91 size_t min_payload_length = DefaultMaxPayloadLength(); 92 CriticalSectionScoped cs(crit_.get()); 93 for (auto* rtp_module : rtp_modules_) { 94 size_t module_payload_length = rtp_module->MaxDataPayloadLength(); 95 if (module_payload_length < min_payload_length) 96 min_payload_length = module_payload_length; 97 } 98 return min_payload_length; 99 } 100 101 } // namespace webrtc 102