OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "webrtc/system_wrappers/include/logging.h" | 22 #include "webrtc/system_wrappers/include/logging.h" |
23 | 23 |
24 namespace webrtc { | 24 namespace webrtc { |
25 | 25 |
26 DecisionLogic* DecisionLogic::Create(int fs_hz, | 26 DecisionLogic* DecisionLogic::Create(int fs_hz, |
27 size_t output_size_samples, | 27 size_t output_size_samples, |
28 NetEqPlayoutMode playout_mode, | 28 NetEqPlayoutMode playout_mode, |
29 DecoderDatabase* decoder_database, | 29 DecoderDatabase* decoder_database, |
30 const PacketBuffer& packet_buffer, | 30 const PacketBuffer& packet_buffer, |
31 DelayManager* delay_manager, | 31 DelayManager* delay_manager, |
32 BufferLevelFilter* buffer_level_filter) { | 32 BufferLevelFilter* buffer_level_filter, |
| 33 const TickTimer& tick_timer) { |
33 switch (playout_mode) { | 34 switch (playout_mode) { |
34 case kPlayoutOn: | 35 case kPlayoutOn: |
35 case kPlayoutStreaming: | 36 case kPlayoutStreaming: |
36 return new DecisionLogicNormal(fs_hz, | 37 return new DecisionLogicNormal( |
37 output_size_samples, | 38 fs_hz, output_size_samples, playout_mode, decoder_database, |
38 playout_mode, | 39 packet_buffer, delay_manager, buffer_level_filter, tick_timer); |
39 decoder_database, | |
40 packet_buffer, | |
41 delay_manager, | |
42 buffer_level_filter); | |
43 case kPlayoutFax: | 40 case kPlayoutFax: |
44 case kPlayoutOff: | 41 case kPlayoutOff: |
45 return new DecisionLogicFax(fs_hz, | 42 return new DecisionLogicFax( |
46 output_size_samples, | 43 fs_hz, output_size_samples, playout_mode, decoder_database, |
47 playout_mode, | 44 packet_buffer, delay_manager, buffer_level_filter, tick_timer); |
48 decoder_database, | |
49 packet_buffer, | |
50 delay_manager, | |
51 buffer_level_filter); | |
52 } | 45 } |
53 // This line cannot be reached, but must be here to avoid compiler errors. | 46 // This line cannot be reached, but must be here to avoid compiler errors. |
54 assert(false); | 47 assert(false); |
55 return NULL; | 48 return NULL; |
56 } | 49 } |
57 | 50 |
58 DecisionLogic::DecisionLogic(int fs_hz, | 51 DecisionLogic::DecisionLogic(int fs_hz, |
59 size_t output_size_samples, | 52 size_t output_size_samples, |
60 NetEqPlayoutMode playout_mode, | 53 NetEqPlayoutMode playout_mode, |
61 DecoderDatabase* decoder_database, | 54 DecoderDatabase* decoder_database, |
62 const PacketBuffer& packet_buffer, | 55 const PacketBuffer& packet_buffer, |
63 DelayManager* delay_manager, | 56 DelayManager* delay_manager, |
64 BufferLevelFilter* buffer_level_filter) | 57 BufferLevelFilter* buffer_level_filter, |
| 58 const TickTimer& tick_timer) |
65 : decoder_database_(decoder_database), | 59 : decoder_database_(decoder_database), |
66 packet_buffer_(packet_buffer), | 60 packet_buffer_(packet_buffer), |
67 delay_manager_(delay_manager), | 61 delay_manager_(delay_manager), |
68 buffer_level_filter_(buffer_level_filter), | 62 buffer_level_filter_(buffer_level_filter), |
| 63 tick_timer_(tick_timer), |
69 cng_state_(kCngOff), | 64 cng_state_(kCngOff), |
70 generated_noise_samples_(0), | |
71 packet_length_samples_(0), | 65 packet_length_samples_(0), |
72 sample_memory_(0), | 66 sample_memory_(0), |
73 prev_time_scale_(false), | 67 prev_time_scale_(false), |
74 timescale_hold_off_(kMinTimescaleInterval), | 68 timescale_countdown_( |
| 69 tick_timer_.GetNewCountdown(kMinTimescaleInterval + 1)), |
75 num_consecutive_expands_(0), | 70 num_consecutive_expands_(0), |
76 playout_mode_(playout_mode) { | 71 playout_mode_(playout_mode) { |
77 delay_manager_->set_streaming_mode(playout_mode_ == kPlayoutStreaming); | 72 delay_manager_->set_streaming_mode(playout_mode_ == kPlayoutStreaming); |
78 SetSampleRate(fs_hz, output_size_samples); | 73 SetSampleRate(fs_hz, output_size_samples); |
79 } | 74 } |
80 | 75 |
| 76 DecisionLogic::~DecisionLogic() = default; |
| 77 |
81 void DecisionLogic::Reset() { | 78 void DecisionLogic::Reset() { |
82 cng_state_ = kCngOff; | 79 cng_state_ = kCngOff; |
83 generated_noise_samples_ = 0; | 80 noise_fast_forward_ = 0; |
84 packet_length_samples_ = 0; | 81 packet_length_samples_ = 0; |
85 sample_memory_ = 0; | 82 sample_memory_ = 0; |
86 prev_time_scale_ = false; | 83 prev_time_scale_ = false; |
87 timescale_hold_off_ = 0; | 84 timescale_countdown_.reset(); |
88 num_consecutive_expands_ = 0; | 85 num_consecutive_expands_ = 0; |
89 } | 86 } |
90 | 87 |
91 void DecisionLogic::SoftReset() { | 88 void DecisionLogic::SoftReset() { |
92 packet_length_samples_ = 0; | 89 packet_length_samples_ = 0; |
93 sample_memory_ = 0; | 90 sample_memory_ = 0; |
94 prev_time_scale_ = false; | 91 prev_time_scale_ = false; |
95 timescale_hold_off_ = kMinTimescaleInterval; | 92 timescale_countdown_ = tick_timer_.GetNewCountdown(kMinTimescaleInterval + 1); |
96 } | 93 } |
97 | 94 |
98 void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) { | 95 void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) { |
99 // TODO(hlundin): Change to an enumerator and skip assert. | 96 // TODO(hlundin): Change to an enumerator and skip assert. |
100 assert(fs_hz == 8000 || fs_hz == 16000 || fs_hz == 32000 || fs_hz == 48000); | 97 assert(fs_hz == 8000 || fs_hz == 16000 || fs_hz == 32000 || fs_hz == 48000); |
101 fs_mult_ = fs_hz / 8000; | 98 fs_mult_ = fs_hz / 8000; |
102 output_size_samples_ = output_size_samples; | 99 output_size_samples_ = output_size_samples; |
103 } | 100 } |
104 | 101 |
105 Operations DecisionLogic::GetDecision(const SyncBuffer& sync_buffer, | 102 Operations DecisionLogic::GetDecision(const SyncBuffer& sync_buffer, |
106 const Expand& expand, | 103 const Expand& expand, |
107 size_t decoder_frame_length, | 104 size_t decoder_frame_length, |
108 const RTPHeader* packet_header, | 105 const RTPHeader* packet_header, |
109 Modes prev_mode, | 106 Modes prev_mode, |
110 bool play_dtmf, bool* reset_decoder) { | 107 bool play_dtmf, |
| 108 size_t noise_samples_played, |
| 109 bool* reset_decoder) { |
111 if (prev_mode == kModeRfc3389Cng || | 110 if (prev_mode == kModeRfc3389Cng || |
112 prev_mode == kModeCodecInternalCng || | 111 prev_mode == kModeCodecInternalCng || |
113 prev_mode == kModeExpand) { | 112 prev_mode == kModeExpand) { |
114 // If last mode was CNG (or Expand, since this could be covering up for | 113 // If last mode was CNG (or Expand, since this could be covering up for |
115 // a lost CNG packet), increase the |generated_noise_samples_| counter. | 114 // a lost CNG packet), remember that CNG is on. This is needed if comfort |
116 generated_noise_samples_ += output_size_samples_; | 115 // noise is interrupted by DTMF. |
117 // Remember that CNG is on. This is needed if comfort noise is interrupted | |
118 // by DTMF. | |
119 if (prev_mode == kModeRfc3389Cng) { | 116 if (prev_mode == kModeRfc3389Cng) { |
120 cng_state_ = kCngRfc3389On; | 117 cng_state_ = kCngRfc3389On; |
121 } else if (prev_mode == kModeCodecInternalCng) { | 118 } else if (prev_mode == kModeCodecInternalCng) { |
122 cng_state_ = kCngInternalOn; | 119 cng_state_ = kCngInternalOn; |
123 } | 120 } |
124 } | 121 } |
125 | 122 |
126 const size_t samples_left = | 123 const size_t samples_left = |
127 sync_buffer.FutureLength() - expand.overlap_length(); | 124 sync_buffer.FutureLength() - expand.overlap_length(); |
128 const size_t cur_size_samples = | 125 const size_t cur_size_samples = |
129 samples_left + packet_buffer_.NumSamplesInBuffer(decoder_database_, | 126 samples_left + packet_buffer_.NumSamplesInBuffer(decoder_database_, |
130 decoder_frame_length); | 127 decoder_frame_length); |
131 | 128 |
132 prev_time_scale_ = prev_time_scale_ && | 129 prev_time_scale_ = prev_time_scale_ && |
133 (prev_mode == kModeAccelerateSuccess || | 130 (prev_mode == kModeAccelerateSuccess || |
134 prev_mode == kModeAccelerateLowEnergy || | 131 prev_mode == kModeAccelerateLowEnergy || |
135 prev_mode == kModePreemptiveExpandSuccess || | 132 prev_mode == kModePreemptiveExpandSuccess || |
136 prev_mode == kModePreemptiveExpandLowEnergy); | 133 prev_mode == kModePreemptiveExpandLowEnergy); |
137 | 134 |
138 FilterBufferLevel(cur_size_samples, prev_mode); | 135 FilterBufferLevel(cur_size_samples, prev_mode); |
139 | 136 |
140 return GetDecisionSpecialized(sync_buffer, expand, decoder_frame_length, | 137 return GetDecisionSpecialized(sync_buffer, expand, decoder_frame_length, |
141 packet_header, prev_mode, play_dtmf, | 138 packet_header, prev_mode, play_dtmf, |
142 reset_decoder); | 139 reset_decoder, noise_samples_played); |
143 } | 140 } |
144 | 141 |
145 void DecisionLogic::ExpandDecision(Operations operation) { | 142 void DecisionLogic::ExpandDecision(Operations operation) { |
146 if (operation == kExpand) { | 143 if (operation == kExpand) { |
147 num_consecutive_expands_++; | 144 num_consecutive_expands_++; |
148 } else { | 145 } else { |
149 num_consecutive_expands_ = 0; | 146 num_consecutive_expands_ = 0; |
150 } | 147 } |
151 } | 148 } |
152 | 149 |
153 void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples, | 150 void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples, |
154 Modes prev_mode) { | 151 Modes prev_mode) { |
155 const int elapsed_time_ms = | |
156 static_cast<int>(output_size_samples_ / (8 * fs_mult_)); | |
157 delay_manager_->UpdateCounters(elapsed_time_ms); | |
158 | |
159 // Do not update buffer history if currently playing CNG since it will bias | 152 // Do not update buffer history if currently playing CNG since it will bias |
160 // the filtered buffer level. | 153 // the filtered buffer level. |
161 if ((prev_mode != kModeRfc3389Cng) && (prev_mode != kModeCodecInternalCng)) { | 154 if ((prev_mode != kModeRfc3389Cng) && (prev_mode != kModeCodecInternalCng)) { |
162 buffer_level_filter_->SetTargetBufferLevel( | 155 buffer_level_filter_->SetTargetBufferLevel( |
163 delay_manager_->base_target_level()); | 156 delay_manager_->base_target_level()); |
164 | 157 |
165 size_t buffer_size_packets = 0; | 158 size_t buffer_size_packets = 0; |
166 if (packet_length_samples_ > 0) { | 159 if (packet_length_samples_ > 0) { |
167 // Calculate size in packets. | 160 // Calculate size in packets. |
168 buffer_size_packets = buffer_size_samples / packet_length_samples_; | 161 buffer_size_packets = buffer_size_samples / packet_length_samples_; |
169 } | 162 } |
170 int sample_memory_local = 0; | 163 int sample_memory_local = 0; |
171 if (prev_time_scale_) { | 164 if (prev_time_scale_) { |
172 sample_memory_local = sample_memory_; | 165 sample_memory_local = sample_memory_; |
173 timescale_hold_off_ = kMinTimescaleInterval; | 166 timescale_countdown_ = tick_timer_.GetNewCountdown(kMinTimescaleInterval); |
174 } | 167 } |
175 buffer_level_filter_->Update(buffer_size_packets, sample_memory_local, | 168 buffer_level_filter_->Update(buffer_size_packets, sample_memory_local, |
176 packet_length_samples_); | 169 packet_length_samples_); |
177 prev_time_scale_ = false; | 170 prev_time_scale_ = false; |
178 } | 171 } |
179 | |
180 timescale_hold_off_ = std::max(timescale_hold_off_ - 1, 0); | |
181 } | 172 } |
182 | 173 |
183 } // namespace webrtc | 174 } // namespace webrtc |
OLD | NEW |