LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/rtp_rtcp/source - tmmbr_help.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 94 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 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/modules/rtp_rtcp/source/tmmbr_help.h"
      12             : 
      13             : #include <algorithm>
      14             : #include <limits>
      15             : 
      16             : #include "webrtc/base/checks.h"
      17             : 
      18             : namespace webrtc {
      19           0 : std::vector<rtcp::TmmbItem> TMMBRHelp::FindBoundingSet(
      20             :     std::vector<rtcp::TmmbItem> candidates) {
      21             :   // Filter out candidates with 0 bitrate.
      22           0 :   for (auto it = candidates.begin(); it != candidates.end();) {
      23           0 :     if (!it->bitrate_bps())
      24           0 :       it = candidates.erase(it);
      25             :     else
      26           0 :       ++it;
      27             :   }
      28             : 
      29           0 :   if (candidates.size() <= 1)
      30           0 :     return candidates;
      31             : 
      32           0 :   size_t num_candidates = candidates.size();
      33             : 
      34             :   // 1. Sort by increasing packet overhead.
      35           0 :   std::sort(candidates.begin(), candidates.end(),
      36           0 :             [](const rtcp::TmmbItem& lhs, const rtcp::TmmbItem& rhs) {
      37           0 :               return lhs.packet_overhead() < rhs.packet_overhead();
      38           0 :             });
      39             : 
      40             :   // 2. For tuples with same overhead, keep the one with the lowest bitrate.
      41           0 :   for (auto it = candidates.begin(); it != candidates.end();) {
      42           0 :     RTC_DCHECK(it->bitrate_bps());
      43           0 :     auto current_min = it;
      44           0 :     auto next_it = it + 1;
      45             :     // Use fact candidates are sorted by overhead, so candidates with same
      46             :     // overhead are adjusted.
      47           0 :     while (next_it != candidates.end() &&
      48           0 :            next_it->packet_overhead() == current_min->packet_overhead()) {
      49           0 :       if (next_it->bitrate_bps() < current_min->bitrate_bps()) {
      50           0 :         current_min->set_bitrate_bps(0);
      51           0 :         current_min = next_it;
      52             :       } else {
      53           0 :         next_it->set_bitrate_bps(0);
      54             :       }
      55           0 :       ++next_it;
      56           0 :       --num_candidates;
      57             :     }
      58           0 :     it = next_it;
      59             :   }
      60             : 
      61             :   // 3. Select and remove tuple with lowest bitrate.
      62             :   // (If more than 1, choose the one with highest overhead).
      63           0 :   auto min_bitrate_it = candidates.end();
      64           0 :   for (auto it = candidates.begin(); it != candidates.end(); ++it) {
      65           0 :     if (it->bitrate_bps()) {
      66           0 :       min_bitrate_it = it;
      67           0 :       break;
      68             :     }
      69             :   }
      70             : 
      71           0 :   for (auto it = min_bitrate_it; it != candidates.end(); ++it) {
      72           0 :     if (it->bitrate_bps() &&
      73           0 :         it->bitrate_bps() <= min_bitrate_it->bitrate_bps()) {
      74             :       // Get min bitrate.
      75           0 :       min_bitrate_it = it;
      76             :     }
      77             :   }
      78             : 
      79           0 :   std::vector<rtcp::TmmbItem> bounding_set;
      80           0 :   bounding_set.reserve(num_candidates);
      81           0 :   std::vector<float> intersection(num_candidates);
      82           0 :   std::vector<float> max_packet_rate(num_candidates);
      83             : 
      84             :   // First member of selected list.
      85           0 :   bounding_set.push_back(*min_bitrate_it);
      86           0 :   intersection[0] = 0;
      87             :   // Calculate its maximum packet rate (where its line crosses x-axis).
      88           0 :   uint16_t packet_overhead = bounding_set.back().packet_overhead();
      89           0 :   if (packet_overhead == 0) {
      90             :     // Avoid division by zero.
      91           0 :     max_packet_rate[0] = std::numeric_limits<float>::max();
      92             :   } else {
      93           0 :     max_packet_rate[0] =
      94           0 :         bounding_set.back().bitrate_bps() / static_cast<float>(packet_overhead);
      95             :   }
      96             :   // Remove from candidate list.
      97           0 :   min_bitrate_it->set_bitrate_bps(0);
      98           0 :   --num_candidates;
      99             : 
     100             :   // 4. Discard from candidate list all tuple with lower overhead
     101             :   // (next tuple must be steeper).
     102           0 :   for (auto it = candidates.begin(); it != candidates.end(); ++it) {
     103           0 :     if (it->bitrate_bps() &&
     104           0 :         it->packet_overhead() < bounding_set.front().packet_overhead()) {
     105           0 :       it->set_bitrate_bps(0);
     106           0 :       --num_candidates;
     107             :     }
     108             :   }
     109             : 
     110           0 :   bool get_new_candidate = true;
     111           0 :   rtcp::TmmbItem cur_candidate;
     112           0 :   while (num_candidates > 0) {
     113           0 :     if (get_new_candidate) {
     114             :       // 5. Remove first remaining tuple from candidate list.
     115           0 :       for (auto it = candidates.begin(); it != candidates.end(); ++it) {
     116           0 :         if (it->bitrate_bps()) {
     117           0 :           cur_candidate = *it;
     118           0 :           it->set_bitrate_bps(0);
     119           0 :           break;
     120             :         }
     121             :       }
     122             :     }
     123             : 
     124             :     // 6. Calculate packet rate and intersection of the current
     125             :     // line with line of last tuple in selected list.
     126           0 :     RTC_DCHECK_NE(cur_candidate.packet_overhead(),
     127           0 :                   bounding_set.back().packet_overhead());
     128           0 :     float packet_rate = static_cast<float>(cur_candidate.bitrate_bps() -
     129           0 :                                            bounding_set.back().bitrate_bps()) /
     130           0 :                         (cur_candidate.packet_overhead() -
     131           0 :                          bounding_set.back().packet_overhead());
     132             : 
     133             :     // 7. If the packet rate is equal or lower than intersection of
     134             :     //    last tuple in selected list,
     135             :     //    remove last tuple in selected list & go back to step 6.
     136           0 :     if (packet_rate <= intersection[bounding_set.size() - 1]) {
     137             :       // Remove last tuple and goto step 6.
     138           0 :       bounding_set.pop_back();
     139           0 :       get_new_candidate = false;
     140             :     } else {
     141             :       // 8. If packet rate is lower than maximum packet rate of
     142             :       // last tuple in selected list, add current tuple to selected
     143             :       // list.
     144           0 :       if (packet_rate < max_packet_rate[bounding_set.size() - 1]) {
     145           0 :         bounding_set.push_back(cur_candidate);
     146           0 :         intersection[bounding_set.size() - 1] = packet_rate;
     147           0 :         uint16_t packet_overhead = bounding_set.back().packet_overhead();
     148           0 :         RTC_DCHECK_NE(packet_overhead, 0);
     149           0 :         max_packet_rate[bounding_set.size() - 1] =
     150           0 :             bounding_set.back().bitrate_bps() /
     151           0 :             static_cast<float>(packet_overhead);
     152             :       }
     153           0 :       --num_candidates;
     154           0 :       get_new_candidate = true;
     155             :     }
     156             : 
     157             :     // 9. Go back to step 5 if any tuple remains in candidate list.
     158             :   }
     159           0 :   RTC_DCHECK(!bounding_set.empty());
     160           0 :   return bounding_set;
     161             : }
     162             : 
     163           0 : bool TMMBRHelp::IsOwner(const std::vector<rtcp::TmmbItem>& bounding,
     164             :                         uint32_t ssrc) {
     165           0 :   for (const rtcp::TmmbItem& item : bounding) {
     166           0 :     if (item.ssrc() == ssrc) {
     167           0 :       return true;
     168             :     }
     169             :   }
     170           0 :   return false;
     171             : }
     172             : 
     173           0 : uint64_t TMMBRHelp::CalcMinBitrateBps(
     174             :     const std::vector<rtcp::TmmbItem>& candidates) {
     175           0 :   RTC_DCHECK(!candidates.empty());
     176           0 :   uint64_t min_bitrate_bps = std::numeric_limits<uint64_t>::max();
     177           0 :   for (const rtcp::TmmbItem& item : candidates)
     178           0 :     if (item.bitrate_bps() < min_bitrate_bps)
     179           0 :       min_bitrate_bps = item.bitrate_bps();
     180           0 :   return min_bitrate_bps;
     181             : }
     182             : }  // namespace webrtc

Generated by: LCOV version 1.13