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/voice_engine/test/auto_test/fakes/loudest_filter.h"
12 
13 #include "webrtc/base/checks.h"
14 
15 namespace voetest {
16 
RemoveTimeoutStreams(uint32_t time_ms)17 void LoudestFilter::RemoveTimeoutStreams(uint32_t time_ms) {
18   auto it = stream_levels_.begin();
19   while (it != stream_levels_.end()) {
20     if (rtc::TimeDiff(time_ms, it->second.last_time_ms) >
21         kStreamTimeOutMs) {
22       stream_levels_.erase(it++);
23     } else {
24       ++it;
25     }
26   }
27 }
28 
FindQuietestStream()29 unsigned int LoudestFilter::FindQuietestStream() {
30   int quietest_level = kInvalidAudioLevel;
31   unsigned int quietest_ssrc = 0;
32   for (auto stream : stream_levels_) {
33     // A smaller value if audio level corresponds to a louder sound.
34     if (quietest_level == kInvalidAudioLevel ||
35         stream.second.audio_level > quietest_level) {
36       quietest_level = stream.second.audio_level;
37       quietest_ssrc = stream.first;
38     }
39   }
40   return quietest_ssrc;
41 }
42 
ForwardThisPacket(const webrtc::RTPHeader & rtp_header)43 bool LoudestFilter::ForwardThisPacket(const webrtc::RTPHeader& rtp_header) {
44   uint32_t time_now_ms = rtc::Time();
45   RemoveTimeoutStreams(time_now_ms);
46 
47   int source_ssrc = rtp_header.ssrc;
48   int audio_level = rtp_header.extension.hasAudioLevel ?
49       rtp_header.extension.audioLevel : kInvalidAudioLevel;
50 
51   if (audio_level == kInvalidAudioLevel) {
52     // Always forward streams with unknown audio level, and don't keep their
53     // states.
54     return true;
55   }
56 
57   auto it = stream_levels_.find(source_ssrc);
58   if (it != stream_levels_.end()) {
59     // Stream has been forwarded. Update and continue to forward.
60     it->second.audio_level = audio_level;
61     it->second.last_time_ms = time_now_ms;
62     return true;
63   }
64 
65   if (stream_levels_.size() < kMaxMixSize) {
66     stream_levels_[source_ssrc].Set(audio_level, time_now_ms);
67     return true;
68   }
69 
70   unsigned int quietest_ssrc = FindQuietestStream();
71   RTC_CHECK_NE(0u, quietest_ssrc);
72   // A smaller value if audio level corresponds to a louder sound.
73   if (audio_level < stream_levels_[quietest_ssrc].audio_level) {
74     stream_levels_.erase(quietest_ssrc);
75     stream_levels_[source_ssrc].Set(audio_level, time_now_ms);
76     return true;
77   }
78   return false;
79 }
80 
81 }  // namespace voetest
82 
83