102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org/*
202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *
402270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *  Use of this source code is governed by a BSD-style license
502270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *  that can be found in the LICENSE file in the root of the source
602270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *  tree. An additional intellectual property rights grant can be found
702270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *  in the file PATENTS.  All contributing project authors may
802270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org */
1002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
117623ce4aeb9130c937ba5836490cbb3a35679e79Peter Boström#include "webrtc/video/payload_router.h"
1202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
1302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org#include "webrtc/base/checks.h"
14ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
15ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
1698f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
1702270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
1802270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgnamespace webrtc {
1902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
2002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgPayloadRouter::PayloadRouter()
2102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org    : crit_(CriticalSectionWrapper::CreateCriticalSection()),
2202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org      active_(false) {}
2302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
2402270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgPayloadRouter::~PayloadRouter() {}
2502270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
26a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.orgsize_t PayloadRouter::DefaultMaxPayloadLength() {
27a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  const size_t kIpUdpSrtpLength = 44;
28a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  return IP_PACKET_SIZE - kIpUdpSrtpLength;
29a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org}
30a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org
3102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgvoid PayloadRouter::SetSendingRtpModules(
3202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org    const std::list<RtpRtcp*>& rtp_modules) {
3302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  CriticalSectionScoped cs(crit_.get());
3402270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  rtp_modules_.clear();
3502270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  rtp_modules_.reserve(rtp_modules.size());
3602270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  for (auto* rtp_module : rtp_modules) {
3702270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org    rtp_modules_.push_back(rtp_module);
3802270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  }
3902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org}
4002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
4102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgvoid PayloadRouter::set_active(bool active) {
4202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  CriticalSectionScoped cs(crit_.get());
4302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  active_ = active;
4402270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org}
4502270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
4602270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgbool PayloadRouter::active() {
4702270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  CriticalSectionScoped cs(crit_.get());
4847d657b68e753d7afb9656c1fa2f421674ed742dmflodman@webrtc.org  return active_ && !rtp_modules_.empty();
4902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org}
5002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
5102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.orgbool PayloadRouter::RoutePayload(FrameType frame_type,
5202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org                                 int8_t payload_type,
5302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org                                 uint32_t time_stamp,
5402270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org                                 int64_t capture_time_ms,
5502270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org                                 const uint8_t* payload_data,
56a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org                                 size_t payload_length,
5702270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org                                 const RTPFragmentationHeader* fragmentation,
5802270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org                                 const RTPVideoHeader* rtp_video_hdr) {
5902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  CriticalSectionScoped cs(crit_.get());
6002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  if (!active_ || rtp_modules_.empty())
6102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org    return false;
6202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
6350e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  // The simulcast index might actually be larger than the number of modules in
6450e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  // case the encoder was processing a frame during a codec reconfig.
6550e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  if (rtp_video_hdr != NULL &&
6650e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org      rtp_video_hdr->simulcastIdx >= rtp_modules_.size())
6750e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org    return false;
6850e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org
6902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  int stream_idx = 0;
7002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  if (rtp_video_hdr != NULL)
7102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org    stream_idx = rtp_video_hdr->simulcastIdx;
7202270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org  return rtp_modules_[stream_idx]->SendOutgoingData(
7302270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org      frame_type, payload_type, time_stamp, capture_time_ms, payload_data,
74a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org      payload_length, fragmentation, rtp_video_hdr) == 0 ? true : false;
75a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org}
76a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org
7750e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.orgvoid PayloadRouter::SetTargetSendBitrates(
7850e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org    const std::vector<uint32_t>& stream_bitrates) {
7950e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  CriticalSectionScoped cs(crit_.get());
8050e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  if (stream_bitrates.size() < rtp_modules_.size()) {
8150e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org    // There can be a size mis-match during codec reconfiguration.
8250e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org    return;
8350e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  }
8450e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  int idx = 0;
8550e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  for (auto* rtp_module : rtp_modules_) {
8650e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org    rtp_module->SetTargetSendBitrate(stream_bitrates[idx++]);
8750e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org  }
8850e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org}
8950e28166afcdf4b2fcc6e331b70e77a284c3a560mflodman@webrtc.org
90a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.orgsize_t PayloadRouter::MaxPayloadLength() const {
91a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  size_t min_payload_length = DefaultMaxPayloadLength();
92a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  CriticalSectionScoped cs(crit_.get());
93a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  for (auto* rtp_module : rtp_modules_) {
94a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org    size_t module_payload_length = rtp_module->MaxDataPayloadLength();
95a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org    if (module_payload_length < min_payload_length)
96a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org      min_payload_length = module_payload_length;
97a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  }
98a4ef2ce29de0c68b869f8d66276bc5acba54cc79mflodman@webrtc.org  return min_payload_length;
9902270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org}
10002270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org
10102270cd718fd2047bbbf99fbe344e3d988480b57mflodman@webrtc.org}  // namespace webrtc
102