gfiber / vendor / opensource / libjingle / 7246b07650052c150a237c99284fc689388f321c / . / talk / base / bandwidthsmoother.cc

/* | |

* libjingle | |

* Copyright 2011, Google Inc. | |

* | |

* Redistribution and use in source and binary forms, with or without | |

* modification, are permitted provided that the following conditions are met: | |

* | |

* 1. Redistributions of source code must retain the above copyright notice, | |

* this list of conditions and the following disclaimer. | |

* 2. Redistributions in binary form must reproduce the above copyright notice, | |

* this list of conditions and the following disclaimer in the documentation | |

* and/or other materials provided with the distribution. | |

* 3. The name of the author may not be used to endorse or promote products | |

* derived from this software without specific prior written permission. | |

* | |

* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |

* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |

* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |

* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |

* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |

* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |

* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |

* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |

* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |

* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |

*/ | |

#include "talk/base/bandwidthsmoother.h" | |

#include <limits.h> | |

namespace talk_base { | |

BandwidthSmoother::BandwidthSmoother(int initial_bandwidth_guess, | |

uint32 time_between_increase, | |

double percent_increase, | |

size_t samples_count_to_average) | |

: time_between_increase_(time_between_increase), | |

percent_increase_(talk_base::_max(1.0, percent_increase)), | |

time_at_last_change_(0), | |

bandwidth_estimation_(initial_bandwidth_guess), | |

accumulator_(samples_count_to_average) { | |

} | |

// Samples a new bandwidth measurement | |

// returns true if the bandwidth estimation changed | |

bool BandwidthSmoother::Sample(uint32 sample_time, int bandwidth) { | |

if (bandwidth < 0) { | |

return false; | |

} | |

accumulator_.AddSample(bandwidth); | |

// Replace bandwidth with the mean of sampled bandwidths. | |

bandwidth = accumulator_.ComputeMean(); | |

if (bandwidth < bandwidth_estimation_) { | |

time_at_last_change_ = sample_time; | |

bandwidth_estimation_ = bandwidth; | |

return true; | |

} | |

const int old_bandwidth_estimation = bandwidth_estimation_; | |

const double increase_threshold_d = percent_increase_ * bandwidth_estimation_; | |

if (increase_threshold_d > INT_MAX) { | |

// If bandwidth goes any higher we would overflow. | |

return false; | |

} | |

const int increase_threshold = static_cast<int>(increase_threshold_d); | |

if (bandwidth < increase_threshold) { | |

time_at_last_change_ = sample_time; | |

// The value of bandwidth_estimation remains the same if we don't exceed | |

// percent_increase_ * bandwidth_estimation_ for at least | |

// time_between_increase_ time. | |

} else if (sample_time >= time_at_last_change_ + time_between_increase_) { | |

time_at_last_change_ = sample_time; | |

if (increase_threshold == 0) { | |

bandwidth_estimation_ = bandwidth / 2; | |

} else { | |

bandwidth_estimation_ = increase_threshold; | |

} | |

} | |

// Else don't make a change. | |

return old_bandwidth_estimation != bandwidth_estimation_; | |

} | |

} // namespace talk_base | |