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 |
11 #include "webrtc/modules/audio_coding/acm2/acm_receiver.h" | 11 #include "webrtc/modules/audio_coding/acm2/acm_receiver.h" |
12 | 12 |
13 #include <stdlib.h> // malloc | 13 #include <stdlib.h> // malloc |
14 | 14 |
15 #include <algorithm> // sort | 15 #include <algorithm> // sort |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
19 #include "webrtc/base/format_macros.h" | 19 #include "webrtc/base/format_macros.h" |
20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/base/safe_conversions.h" |
21 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 22 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
22 #include "webrtc/common_types.h" | 23 #include "webrtc/common_types.h" |
23 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" | 24 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" |
24 #include "webrtc/modules/audio_coding/acm2/acm_resampler.h" | 25 #include "webrtc/modules/audio_coding/acm2/acm_resampler.h" |
25 #include "webrtc/modules/audio_coding/acm2/call_statistics.h" | 26 #include "webrtc/modules/audio_coding/acm2/call_statistics.h" |
26 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" | 27 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" |
27 #include "webrtc/system_wrappers/include/clock.h" | 28 #include "webrtc/system_wrappers/include/clock.h" |
28 #include "webrtc/system_wrappers/include/tick_util.h" | 29 #include "webrtc/system_wrappers/include/tick_util.h" |
29 #include "webrtc/system_wrappers/include/trace.h" | 30 #include "webrtc/system_wrappers/include/trace.h" |
30 | 31 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 *i == RentACodec::CodecId::kCNWB || | 114 *i == RentACodec::CodecId::kCNWB || |
114 *i == RentACodec::CodecId::kCNSWB || | 115 *i == RentACodec::CodecId::kCNSWB || |
115 *i == RentACodec::CodecId::kCNFB)); | 116 *i == RentACodec::CodecId::kCNFB)); |
116 } | 117 } |
117 | 118 |
118 } // namespace | 119 } // namespace |
119 | 120 |
120 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) | 121 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) |
121 : last_audio_decoder_(nullptr), | 122 : last_audio_decoder_(nullptr), |
122 previous_audio_activity_(AudioFrame::kVadPassive), | 123 previous_audio_activity_(AudioFrame::kVadPassive), |
123 audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), | |
124 last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), | 124 last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), |
125 neteq_(NetEq::Create(config.neteq_config)), | 125 neteq_(NetEq::Create(config.neteq_config)), |
126 vad_enabled_(config.neteq_config.enable_post_decode_vad), | 126 vad_enabled_(config.neteq_config.enable_post_decode_vad), |
127 clock_(config.clock), | 127 clock_(config.clock), |
128 resampled_last_output_frame_(true) { | 128 resampled_last_output_frame_(true) { |
129 assert(clock_); | 129 assert(clock_); |
130 memset(audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples); | |
131 memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples); | 130 memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples); |
132 } | 131 } |
133 | 132 |
134 AcmReceiver::~AcmReceiver() { | 133 AcmReceiver::~AcmReceiver() { |
135 delete neteq_; | 134 delete neteq_; |
136 } | 135 } |
137 | 136 |
138 int AcmReceiver::SetMinimumDelay(int delay_ms) { | 137 int AcmReceiver::SetMinimumDelay(int delay_ms) { |
139 if (neteq_->SetMinimumDelay(delay_ms)) | 138 if (neteq_->SetMinimumDelay(delay_ms)) |
140 return 0; | 139 return 0; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 0) { | 200 0) { |
202 LOG(LERROR) << "AcmReceiver::InsertPacket " | 201 LOG(LERROR) << "AcmReceiver::InsertPacket " |
203 << static_cast<int>(header->payloadType) | 202 << static_cast<int>(header->payloadType) |
204 << " Failed to insert packet"; | 203 << " Failed to insert packet"; |
205 return -1; | 204 return -1; |
206 } | 205 } |
207 return 0; | 206 return 0; |
208 } | 207 } |
209 | 208 |
210 int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { | 209 int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { |
211 enum NetEqOutputType type; | |
212 size_t samples_per_channel; | |
213 size_t num_channels; | |
214 | |
215 // Accessing members, take the lock. | 210 // Accessing members, take the lock. |
216 rtc::CritScope lock(&crit_sect_); | 211 rtc::CritScope lock(&crit_sect_); |
217 | 212 |
218 // Always write the output to |audio_buffer_| first. | 213 enum NetEqOutputType type; |
219 if (neteq_->GetAudio(AudioFrame::kMaxDataSizeSamples, | 214 if (neteq_->GetAudio(audio_frame, &type) != NetEq::kOK) { |
220 audio_buffer_.get(), | |
221 &samples_per_channel, | |
222 &num_channels, | |
223 &type) != NetEq::kOK) { | |
224 LOG(LERROR) << "AcmReceiver::GetAudio - NetEq Failed."; | 215 LOG(LERROR) << "AcmReceiver::GetAudio - NetEq Failed."; |
225 return -1; | 216 return -1; |
226 } | 217 } |
227 | 218 |
228 const int current_sample_rate_hz = neteq_->last_output_sample_rate_hz(); | 219 const int current_sample_rate_hz = neteq_->last_output_sample_rate_hz(); |
229 | 220 |
230 // Update if resampling is required. | 221 // Update if resampling is required. |
231 const bool need_resampling = | 222 const bool need_resampling = |
232 (desired_freq_hz != -1) && (current_sample_rate_hz != desired_freq_hz); | 223 (desired_freq_hz != -1) && (current_sample_rate_hz != desired_freq_hz); |
233 | 224 |
234 if (need_resampling && !resampled_last_output_frame_) { | 225 if (need_resampling && !resampled_last_output_frame_) { |
235 // Prime the resampler with the last frame. | 226 // Prime the resampler with the last frame. |
236 int16_t temp_output[AudioFrame::kMaxDataSizeSamples]; | 227 int16_t temp_output[AudioFrame::kMaxDataSizeSamples]; |
237 int samples_per_channel_int = resampler_.Resample10Msec( | 228 int samples_per_channel_int = resampler_.Resample10Msec( |
238 last_audio_buffer_.get(), current_sample_rate_hz, desired_freq_hz, | 229 last_audio_buffer_.get(), current_sample_rate_hz, desired_freq_hz, |
239 num_channels, AudioFrame::kMaxDataSizeSamples, temp_output); | 230 audio_frame->num_channels_, AudioFrame::kMaxDataSizeSamples, |
| 231 temp_output); |
240 if (samples_per_channel_int < 0) { | 232 if (samples_per_channel_int < 0) { |
241 LOG(LERROR) << "AcmReceiver::GetAudio - " | 233 LOG(LERROR) << "AcmReceiver::GetAudio - " |
242 "Resampling last_audio_buffer_ failed."; | 234 "Resampling last_audio_buffer_ failed."; |
243 return -1; | 235 return -1; |
244 } | 236 } |
245 samples_per_channel = static_cast<size_t>(samples_per_channel_int); | |
246 } | 237 } |
247 | 238 |
248 // The audio in |audio_buffer_| is tansferred to |audio_frame_| below, either | |
249 // through resampling, or through straight memcpy. | |
250 // TODO(henrik.lundin) Glitches in the output may appear if the output rate | 239 // TODO(henrik.lundin) Glitches in the output may appear if the output rate |
251 // from NetEq changes. See WebRTC issue 3923. | 240 // from NetEq changes. See WebRTC issue 3923. |
252 if (need_resampling) { | 241 if (need_resampling) { |
253 int samples_per_channel_int = resampler_.Resample10Msec( | 242 int samples_per_channel_int = resampler_.Resample10Msec( |
254 audio_buffer_.get(), current_sample_rate_hz, desired_freq_hz, | 243 audio_frame->data_, current_sample_rate_hz, desired_freq_hz, |
255 num_channels, AudioFrame::kMaxDataSizeSamples, audio_frame->data_); | 244 audio_frame->num_channels_, AudioFrame::kMaxDataSizeSamples, |
| 245 audio_frame->data_); |
256 if (samples_per_channel_int < 0) { | 246 if (samples_per_channel_int < 0) { |
257 LOG(LERROR) << "AcmReceiver::GetAudio - Resampling audio_buffer_ failed."; | 247 LOG(LERROR) << "AcmReceiver::GetAudio - Resampling audio_buffer_ failed."; |
258 return -1; | 248 return -1; |
259 } | 249 } |
260 samples_per_channel = static_cast<size_t>(samples_per_channel_int); | 250 audio_frame->samples_per_channel_ = |
| 251 static_cast<size_t>(samples_per_channel_int); |
| 252 audio_frame->sample_rate_hz_ = desired_freq_hz; |
| 253 RTC_DCHECK_EQ( |
| 254 audio_frame->sample_rate_hz_, |
| 255 rtc::checked_cast<int>(audio_frame->samples_per_channel_ * 100)); |
261 resampled_last_output_frame_ = true; | 256 resampled_last_output_frame_ = true; |
262 } else { | 257 } else { |
263 resampled_last_output_frame_ = false; | 258 resampled_last_output_frame_ = false; |
264 // We might end up here ONLY if codec is changed. | 259 // We might end up here ONLY if codec is changed. |
265 memcpy(audio_frame->data_, | |
266 audio_buffer_.get(), | |
267 samples_per_channel * num_channels * sizeof(int16_t)); | |
268 } | 260 } |
269 | 261 |
270 // Swap buffers, so that the current audio is stored in |last_audio_buffer_| | 262 // Store current audio in |last_audio_buffer_| for next time. |
271 // for next time. | 263 memcpy(last_audio_buffer_.get(), audio_frame->data_, |
272 audio_buffer_.swap(last_audio_buffer_); | 264 sizeof(int16_t) * audio_frame->samples_per_channel_ * |
273 | 265 audio_frame->num_channels_); |
274 audio_frame->num_channels_ = num_channels; | |
275 audio_frame->samples_per_channel_ = samples_per_channel; | |
276 audio_frame->sample_rate_hz_ = static_cast<int>(samples_per_channel * 100); | |
277 | 266 |
278 // Should set |vad_activity| before calling SetAudioFrameActivityAndType(). | 267 // Should set |vad_activity| before calling SetAudioFrameActivityAndType(). |
279 audio_frame->vad_activity_ = previous_audio_activity_; | 268 audio_frame->vad_activity_ = previous_audio_activity_; |
280 SetAudioFrameActivityAndType(vad_enabled_, type, audio_frame); | 269 SetAudioFrameActivityAndType(vad_enabled_, type, audio_frame); |
281 previous_audio_activity_ = audio_frame->vad_activity_; | 270 previous_audio_activity_ = audio_frame->vad_activity_; |
282 call_stats_.DecodedByNetEq(audio_frame->speech_type_); | 271 call_stats_.DecodedByNetEq(audio_frame->speech_type_); |
283 | 272 |
284 // Computes the RTP timestamp of the first sample in |audio_frame| from | 273 // Computes the RTP timestamp of the first sample in |audio_frame| from |
285 // |GetPlayoutTimestamp|, which is the timestamp of the last sample of | 274 // |GetPlayoutTimestamp|, which is the timestamp of the last sample of |
286 // |audio_frame|. | 275 // |audio_frame|. |
| 276 // TODO(henrik.lundin) Move setting of audio_frame->timestamp_ inside NetEq. |
287 uint32_t playout_timestamp = 0; | 277 uint32_t playout_timestamp = 0; |
288 if (GetPlayoutTimestamp(&playout_timestamp)) { | 278 if (GetPlayoutTimestamp(&playout_timestamp)) { |
289 audio_frame->timestamp_ = playout_timestamp - | 279 audio_frame->timestamp_ = playout_timestamp - |
290 static_cast<uint32_t>(audio_frame->samples_per_channel_); | 280 static_cast<uint32_t>(audio_frame->samples_per_channel_); |
291 } else { | 281 } else { |
292 // Remain 0 until we have a valid |playout_timestamp|. | 282 // Remain 0 until we have a valid |playout_timestamp|. |
293 audio_frame->timestamp_ = 0; | 283 audio_frame->timestamp_ = 0; |
294 } | 284 } |
295 | 285 |
296 return 0; | 286 return 0; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 | 514 |
525 void AcmReceiver::GetDecodingCallStatistics( | 515 void AcmReceiver::GetDecodingCallStatistics( |
526 AudioDecodingCallStats* stats) const { | 516 AudioDecodingCallStats* stats) const { |
527 rtc::CritScope lock(&crit_sect_); | 517 rtc::CritScope lock(&crit_sect_); |
528 *stats = call_stats_.GetDecodingStatistics(); | 518 *stats = call_stats_.GetDecodingStatistics(); |
529 } | 519 } |
530 | 520 |
531 } // namespace acm2 | 521 } // namespace acm2 |
532 | 522 |
533 } // namespace webrtc | 523 } // namespace webrtc |
OLD | NEW |