Change NetEq::GetAudio to use AudioFrame
With this change, NetEq now uses AudioFrame as output type, like the
surrounding functions in ACM and VoiceEngine already do.
The computational savings is probably slim, since one memcpy is
removed while another one is added (both in AcmReceiver::GetAudio).
More simplifications and clean-up will be done in
AcmReceiver::GetAudio in future CLs.
BUG=webrtc:5607
Review URL: https://codereview.webrtc.org/1750353002
Cr-Commit-Position: refs/heads/master@{#11874}
diff --git a/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.cc b/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.cc
index ec3f4fc..e4a34a7 100644
--- a/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.cc
+++ b/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.cc
@@ -159,7 +159,7 @@
while (clock_.TimeInMilliseconds() < packet->time_ms()) {
AudioFrame output_frame;
EXPECT_EQ(0, acm_->PlayoutData10Ms(output_freq_hz_, &output_frame));
- EXPECT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
+ ASSERT_EQ(output_freq_hz_, output_frame.sample_rate_hz_);
const size_t samples_per_block =
static_cast<size_t>(output_freq_hz_ * 10 / 1000);
EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_);
diff --git a/webrtc/modules/audio_coding/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/acm2/acm_receiver.cc
index 39d8a0d..02d165a 100644
--- a/webrtc/modules/audio_coding/acm2/acm_receiver.cc
+++ b/webrtc/modules/audio_coding/acm2/acm_receiver.cc
@@ -18,6 +18,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/format_macros.h"
#include "webrtc/base/logging.h"
+#include "webrtc/base/safe_conversions.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
@@ -120,14 +121,12 @@
AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config)
: last_audio_decoder_(nullptr),
previous_audio_activity_(AudioFrame::kVadPassive),
- audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]),
neteq_(NetEq::Create(config.neteq_config)),
vad_enabled_(config.neteq_config.enable_post_decode_vad),
clock_(config.clock),
resampled_last_output_frame_(true) {
assert(clock_);
- memset(audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples);
memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples);
}
@@ -208,19 +207,11 @@
}
int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) {
- enum NetEqOutputType type;
- size_t samples_per_channel;
- size_t num_channels;
-
// Accessing members, take the lock.
rtc::CritScope lock(&crit_sect_);
- // Always write the output to |audio_buffer_| first.
- if (neteq_->GetAudio(AudioFrame::kMaxDataSizeSamples,
- audio_buffer_.get(),
- &samples_per_channel,
- &num_channels,
- &type) != NetEq::kOK) {
+ enum NetEqOutputType type;
+ if (neteq_->GetAudio(audio_frame, &type) != NetEq::kOK) {
LOG(LERROR) << "AcmReceiver::GetAudio - NetEq Failed.";
return -1;
}
@@ -236,44 +227,42 @@
int16_t temp_output[AudioFrame::kMaxDataSizeSamples];
int samples_per_channel_int = resampler_.Resample10Msec(
last_audio_buffer_.get(), current_sample_rate_hz, desired_freq_hz,
- num_channels, AudioFrame::kMaxDataSizeSamples, temp_output);
+ audio_frame->num_channels_, AudioFrame::kMaxDataSizeSamples,
+ temp_output);
if (samples_per_channel_int < 0) {
LOG(LERROR) << "AcmReceiver::GetAudio - "
"Resampling last_audio_buffer_ failed.";
return -1;
}
- samples_per_channel = static_cast<size_t>(samples_per_channel_int);
}
- // The audio in |audio_buffer_| is tansferred to |audio_frame_| below, either
- // through resampling, or through straight memcpy.
// TODO(henrik.lundin) Glitches in the output may appear if the output rate
// from NetEq changes. See WebRTC issue 3923.
if (need_resampling) {
int samples_per_channel_int = resampler_.Resample10Msec(
- audio_buffer_.get(), current_sample_rate_hz, desired_freq_hz,
- num_channels, AudioFrame::kMaxDataSizeSamples, audio_frame->data_);
+ audio_frame->data_, current_sample_rate_hz, desired_freq_hz,
+ audio_frame->num_channels_, AudioFrame::kMaxDataSizeSamples,
+ audio_frame->data_);
if (samples_per_channel_int < 0) {
LOG(LERROR) << "AcmReceiver::GetAudio - Resampling audio_buffer_ failed.";
return -1;
}
- samples_per_channel = static_cast<size_t>(samples_per_channel_int);
+ audio_frame->samples_per_channel_ =
+ static_cast<size_t>(samples_per_channel_int);
+ audio_frame->sample_rate_hz_ = desired_freq_hz;
+ RTC_DCHECK_EQ(
+ audio_frame->sample_rate_hz_,
+ rtc::checked_cast<int>(audio_frame->samples_per_channel_ * 100));
resampled_last_output_frame_ = true;
} else {
resampled_last_output_frame_ = false;
// We might end up here ONLY if codec is changed.
- memcpy(audio_frame->data_,
- audio_buffer_.get(),
- samples_per_channel * num_channels * sizeof(int16_t));
}
- // Swap buffers, so that the current audio is stored in |last_audio_buffer_|
- // for next time.
- audio_buffer_.swap(last_audio_buffer_);
-
- audio_frame->num_channels_ = num_channels;
- audio_frame->samples_per_channel_ = samples_per_channel;
- audio_frame->sample_rate_hz_ = static_cast<int>(samples_per_channel * 100);
+ // Store current audio in |last_audio_buffer_| for next time.
+ memcpy(last_audio_buffer_.get(), audio_frame->data_,
+ sizeof(int16_t) * audio_frame->samples_per_channel_ *
+ audio_frame->num_channels_);
// Should set |vad_activity| before calling SetAudioFrameActivityAndType().
audio_frame->vad_activity_ = previous_audio_activity_;
@@ -284,6 +273,7 @@
// Computes the RTP timestamp of the first sample in |audio_frame| from
// |GetPlayoutTimestamp|, which is the timestamp of the last sample of
// |audio_frame|.
+ // TODO(henrik.lundin) Move setting of audio_frame->timestamp_ inside NetEq.
uint32_t playout_timestamp = 0;
if (GetPlayoutTimestamp(&playout_timestamp)) {
audio_frame->timestamp_ = playout_timestamp -
diff --git a/webrtc/modules/audio_coding/acm2/acm_receiver.h b/webrtc/modules/audio_coding/acm2/acm_receiver.h
index 476f29d..ae3969b 100644
--- a/webrtc/modules/audio_coding/acm2/acm_receiver.h
+++ b/webrtc/modules/audio_coding/acm2/acm_receiver.h
@@ -280,9 +280,6 @@
const Decoder* last_audio_decoder_ GUARDED_BY(crit_sect_);
AudioFrame::VADActivity previous_audio_activity_ GUARDED_BY(crit_sect_);
ACMResampler resampler_ GUARDED_BY(crit_sect_);
- // Used in GetAudio, declared as member to avoid allocating every 10ms.
- // TODO(henrik.lundin) Stack-allocate in GetAudio instead?
- std::unique_ptr<int16_t[]> audio_buffer_ GUARDED_BY(crit_sect_);
std::unique_ptr<int16_t[]> last_audio_buffer_ GUARDED_BY(crit_sect_);
CallStatistics call_stats_ GUARDED_BY(crit_sect_);
NetEq* neteq_;
diff --git a/webrtc/modules/audio_coding/neteq/audio_multi_vector.cc b/webrtc/modules/audio_coding/neteq/audio_multi_vector.cc
index 1381895..bd38c43 100644
--- a/webrtc/modules/audio_coding/neteq/audio_multi_vector.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_multi_vector.cc
@@ -14,6 +14,7 @@
#include <algorithm>
+#include "webrtc/base/checks.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -130,9 +131,7 @@
size_t AudioMultiVector::ReadInterleavedFromIndex(size_t start_index,
size_t length,
int16_t* destination) const {
- if (!destination) {
- return 0;
- }
+ RTC_DCHECK(destination);
size_t index = 0; // Number of elements written to |destination| so far.
assert(start_index <= Size());
start_index = std::min(start_index, Size());
diff --git a/webrtc/modules/audio_coding/neteq/audio_multi_vector_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
index 1921dc2..864c2b2 100644
--- a/webrtc/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
@@ -208,16 +208,6 @@
delete [] output;
}
-// Try to read to a NULL pointer. Expected to return 0.
-TEST_P(AudioMultiVectorTest, ReadInterleavedToNull) {
- AudioMultiVector vec(num_channels_);
- vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
- int16_t* output = NULL;
- // Read 5 samples.
- size_t read_samples = 5;
- EXPECT_EQ(0u, vec.ReadInterleaved(read_samples, output));
-}
-
// Test the PopFront method.
TEST_P(AudioMultiVectorTest, PopFront) {
AudioMultiVector vec(num_channels_);
diff --git a/webrtc/modules/audio_coding/neteq/include/neteq.h b/webrtc/modules/audio_coding/neteq/include/neteq.h
index 1322223..dff09db 100644
--- a/webrtc/modules/audio_coding/neteq/include/neteq.h
+++ b/webrtc/modules/audio_coding/neteq/include/neteq.h
@@ -23,6 +23,7 @@
namespace webrtc {
// Forward declarations.
+class AudioFrame;
struct WebRtcRTPHeader;
struct NetEqNetworkStatistics {
@@ -163,16 +164,12 @@
uint32_t receive_timestamp) = 0;
// Instructs NetEq to deliver 10 ms of audio data. The data is written to
- // |output_audio|, which can hold (at least) |max_length| elements.
- // The number of channels that were written to the output is provided in
- // the output variable |num_channels|, and each channel contains
- // |samples_per_channel| elements. If more than one channel is written,
- // the samples are interleaved.
+ // |audio_frame|. All data in |audio_frame| is wiped; |data_|, |interleaved_|,
+ // |num_channels_|, and |samples_per_channel_| are updated upon success. If
+ // an error is returned, some fields may not have been updated.
// The speech type is written to |type|, if |type| is not NULL.
// Returns kOK on success, or kFail in case of an error.
- virtual int GetAudio(size_t max_length, int16_t* output_audio,
- size_t* samples_per_channel, size_t* num_channels,
- NetEqOutputType* type) = 0;
+ virtual int GetAudio(AudioFrame* audio_frame, NetEqOutputType* type) = 0;
// Associates |rtp_payload_type| with |codec| and |codec_name|, and stores the
// information in the codec database. Returns 0 on success, -1 on failure.
diff --git a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
index 73eff45..7712b24 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc
@@ -17,6 +17,7 @@
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
#include "webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
@@ -188,25 +189,19 @@
void GetAndVerifyOutput() override {
NetEqOutputType output_type;
- size_t samples_per_channel;
- size_t num_channels;
// Get audio from internal decoder instance.
EXPECT_EQ(NetEq::kOK,
- neteq_internal_->GetAudio(kMaxBlockSize,
- output_internal_,
- &samples_per_channel,
- &num_channels,
- &output_type));
- EXPECT_EQ(1u, num_channels);
+ neteq_internal_->GetAudio(&output_internal_, &output_type));
+ EXPECT_EQ(1u, output_internal_.num_channels_);
EXPECT_EQ(static_cast<size_t>(kOutputLengthMs * sample_rate_hz_ / 1000),
- samples_per_channel);
+ output_internal_.samples_per_channel_);
// Get audio from external decoder instance.
- samples_per_channel = GetOutputAudio(kMaxBlockSize, output_, &output_type);
+ GetOutputAudio(&output_, &output_type);
- for (size_t i = 0; i < samples_per_channel; ++i) {
- ASSERT_EQ(output_[i], output_internal_[i]) <<
- "Diff in sample " << i << ".";
+ for (size_t i = 0; i < output_.samples_per_channel_; ++i) {
+ ASSERT_EQ(output_.data_[i], output_internal_.data_[i])
+ << "Diff in sample " << i << ".";
}
}
@@ -227,8 +222,8 @@
private:
int sample_rate_hz_;
std::unique_ptr<NetEq> neteq_internal_;
- int16_t output_internal_[kMaxBlockSize];
- int16_t output_[kMaxBlockSize];
+ AudioFrame output_internal_;
+ AudioFrame output_;
};
TEST_F(NetEqExternalVsInternalDecoderTest, RunTest) {
@@ -291,9 +286,9 @@
}
void GetAndVerifyOutput() override {
- size_t num_samples;
+ AudioFrame output;
NetEqOutputType output_type;
- num_samples = GetOutputAudio(kMaxBlockSize, output_, &output_type);
+ GetOutputAudio(&output, &output_type);
UpdateState(output_type);
if (test_state_ == kExpandPhase || test_state_ == kFadedExpandPhase) {
@@ -301,8 +296,9 @@
return;
}
- for (size_t i = 0; i < num_samples; ++i) {
- if (output_[i] != 0)
+ ASSERT_EQ(1u, output.num_channels_);
+ for (size_t i = 0; i < output.samples_per_channel_; ++i) {
+ if (output.data_[i] != 0)
return;
}
EXPECT_TRUE(false)
@@ -321,9 +317,6 @@
}
TestStates test_state_;
-
- private:
- int16_t output_[kMaxBlockSize];
};
TEST_F(LargeTimestampJumpTest, JumpLongerThanHalfRange) {
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
index 9369982..f899d07 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
@@ -148,13 +148,13 @@
return kOK;
}
-int NetEqImpl::GetAudio(size_t max_length, int16_t* output_audio,
- size_t* samples_per_channel, size_t* num_channels,
- NetEqOutputType* type) {
+int NetEqImpl::GetAudio(AudioFrame* audio_frame, NetEqOutputType* type) {
TRACE_EVENT0("webrtc", "NetEqImpl::GetAudio");
rtc::CritScope lock(&crit_sect_);
- int error = GetAudioInternal(max_length, output_audio, samples_per_channel,
- num_channels);
+ int error = GetAudioInternal(audio_frame);
+ RTC_DCHECK_EQ(
+ audio_frame->sample_rate_hz_,
+ rtc::checked_cast<int>(audio_frame->samples_per_channel_ * 100));
if (error != 0) {
error_code_ = error;
return kFail;
@@ -162,8 +162,7 @@
if (type) {
*type = LastOutputType();
}
- last_output_sample_rate_hz_ =
- rtc::checked_cast<int>(*samples_per_channel * 100);
+ last_output_sample_rate_hz_ = audio_frame->sample_rate_hz_;
RTC_DCHECK(last_output_sample_rate_hz_ == 8000 ||
last_output_sample_rate_hz_ == 16000 ||
last_output_sample_rate_hz_ == 32000 ||
@@ -739,10 +738,7 @@
return 0;
}
-int NetEqImpl::GetAudioInternal(size_t max_length,
- int16_t* output,
- size_t* samples_per_channel,
- size_t* num_channels) {
+int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame) {
PacketList packet_list;
DtmfEvent dtmf_event;
Operations operation;
@@ -857,16 +853,18 @@
// Extract data from |sync_buffer_| to |output|.
size_t num_output_samples_per_channel = output_size_samples_;
size_t num_output_samples = output_size_samples_ * sync_buffer_->Channels();
- if (num_output_samples > max_length) {
- LOG(LS_WARNING) << "Output array is too short. " << max_length << " < " <<
- output_size_samples_ << " * " << sync_buffer_->Channels();
- num_output_samples = max_length;
- num_output_samples_per_channel = max_length / sync_buffer_->Channels();
+ if (num_output_samples > AudioFrame::kMaxDataSizeSamples) {
+ LOG(LS_WARNING) << "Output array is too short. "
+ << AudioFrame::kMaxDataSizeSamples << " < "
+ << output_size_samples_ << " * "
+ << sync_buffer_->Channels();
+ num_output_samples = AudioFrame::kMaxDataSizeSamples;
+ num_output_samples_per_channel =
+ AudioFrame::kMaxDataSizeSamples / sync_buffer_->Channels();
}
- const size_t samples_from_sync =
- sync_buffer_->GetNextAudioInterleaved(num_output_samples_per_channel,
- output);
- *num_channels = sync_buffer_->Channels();
+ sync_buffer_->GetNextAudioInterleaved(num_output_samples_per_channel,
+ audio_frame);
+ audio_frame->sample_rate_hz_ = fs_hz_;
if (sync_buffer_->FutureLength() < expand_->overlap_length()) {
// The sync buffer should always contain |overlap_length| samples, but now
// too many samples have been extracted. Reinstall the |overlap_length|
@@ -877,22 +875,22 @@
sync_buffer_->set_next_index(sync_buffer_->next_index() -
missing_lookahead_samples);
}
- if (samples_from_sync != output_size_samples_) {
- LOG(LS_ERROR) << "samples_from_sync (" << samples_from_sync
+ if (audio_frame->samples_per_channel_ != output_size_samples_) {
+ LOG(LS_ERROR) << "audio_frame->samples_per_channel_ ("
+ << audio_frame->samples_per_channel_
<< ") != output_size_samples_ (" << output_size_samples_
<< ")";
// TODO(minyue): treatment of under-run, filling zeros
- memset(output, 0, num_output_samples * sizeof(int16_t));
- *samples_per_channel = output_size_samples_;
+ memset(audio_frame->data_, 0, num_output_samples * sizeof(int16_t));
return kSampleUnderrun;
}
- *samples_per_channel = output_size_samples_;
// Should always have overlap samples left in the |sync_buffer_|.
RTC_DCHECK_GE(sync_buffer_->FutureLength(), expand_->overlap_length());
if (play_dtmf) {
- return_value = DtmfOverdub(dtmf_event, sync_buffer_->Channels(), output);
+ return_value =
+ DtmfOverdub(dtmf_event, sync_buffer_->Channels(), audio_frame->data_);
}
// Update the background noise parameters if last operation wrote data
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.h b/webrtc/modules/audio_coding/neteq/neteq_impl.h
index 78c678c..4575864 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.h
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.h
@@ -96,19 +96,7 @@
int InsertSyncPacket(const WebRtcRTPHeader& rtp_header,
uint32_t receive_timestamp) override;
- // Instructs NetEq to deliver 10 ms of audio data. The data is written to
- // |output_audio|, which can hold (at least) |max_length| elements.
- // The number of channels that were written to the output is provided in
- // the output variable |num_channels|, and each channel contains
- // |samples_per_channel| elements. If more than one channel is written,
- // the samples are interleaved.
- // The speech type is written to |type|, if |type| is not NULL.
- // Returns kOK on success, or kFail in case of an error.
- int GetAudio(size_t max_length,
- int16_t* output_audio,
- size_t* samples_per_channel,
- size_t* num_channels,
- NetEqOutputType* type) override;
+ int GetAudio(AudioFrame* audio_frame, NetEqOutputType* type) override;
int RegisterPayloadType(NetEqDecoder codec,
const std::string& codec_name,
@@ -211,16 +199,9 @@
bool is_sync_packet)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
- // Delivers 10 ms of audio data. The data is written to |output|, which can
- // hold (at least) |max_length| elements. The number of channels that were
- // written to the output is provided in the output variable |num_channels|,
- // and each channel contains |samples_per_channel| elements. If more than one
- // channel is written, the samples are interleaved.
+ // Delivers 10 ms of audio data. The data is written to |audio_frame|.
// Returns 0 on success, otherwise an error code.
- int GetAudioInternal(size_t max_length,
- int16_t* output,
- size_t* samples_per_channel,
- size_t* num_channels)
+ int GetAudioInternal(AudioFrame* audio_frame)
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
// Provides a decision to the GetAudioInternal method. The decision what to
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
index f734883..cb4405d 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -28,6 +28,7 @@
#include "webrtc/modules/audio_coding/neteq/preemptive_expand.h"
#include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
#include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h"
+#include "webrtc/modules/include/module_common_types.h"
using ::testing::AtLeast;
using ::testing::Return;
@@ -464,16 +465,11 @@
// Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
- EXPECT_EQ(
- NetEq::kOK,
- neteq_->GetAudio(
- kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
- ASSERT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type);
// Start with a simple check that the fake decoder is behaving as expected.
@@ -485,7 +481,8 @@
// timestamp should match the playout timestamp.
uint32_t timestamp = 0;
EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp));
- EXPECT_EQ(rtp_header.header.timestamp + output[samples_per_channel - 1],
+ EXPECT_EQ(rtp_header.header.timestamp +
+ output.data_[output.samples_per_channel_ - 1],
timestamp);
// Check the timestamp for the last value in the sync buffer. This should
@@ -497,8 +494,9 @@
// Check that the number of samples still to play from the sync buffer add
// up with what was already played out.
- EXPECT_EQ(kPayloadLengthSamples - output[samples_per_channel - 1],
- sync_buffer->FutureLength());
+ EXPECT_EQ(
+ kPayloadLengthSamples - output.data_[output.samples_per_channel_ - 1],
+ sync_buffer->FutureLength());
}
TEST_F(NetEqImplTest, ReorderedPacket) {
@@ -543,16 +541,11 @@
// Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
- EXPECT_EQ(
- NetEq::kOK,
- neteq_->GetAudio(
- kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
- ASSERT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type);
// Insert two more packets. The first one is out of order, and is already too
@@ -578,12 +571,9 @@
Return(kPayloadLengthSamples)));
// Pull audio once.
- EXPECT_EQ(
- NetEq::kOK,
- neteq_->GetAudio(
- kMaxOutputSize, output, &samples_per_channel, &num_channels, &type));
- ASSERT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type);
// Now check the packet buffer, and make sure it is empty, since the
@@ -620,16 +610,12 @@
// Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- ASSERT_LE(samples_per_channel, kMaxOutputSize);
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputPLC, type);
// Register the payload type.
@@ -647,12 +633,10 @@
// Pull audio repeatedly and make sure we get normal output, that is not PLC.
for (size_t i = 0; i < 3; ++i) {
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- ASSERT_LE(samples_per_channel, kMaxOutputSize);
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type)
<< "NetEq did not decode the packets as expected.";
}
@@ -732,9 +716,7 @@
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
uint32_t timestamp;
uint32_t last_timestamp;
NetEqOutputType type;
@@ -752,19 +734,15 @@
50 * kSampleRateKhz, 10 * kSampleRateKhz
};
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
EXPECT_TRUE(neteq_->GetPlayoutTimestamp(&last_timestamp));
for (size_t i = 1; i < 6; ++i) {
- ASSERT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(expected_type[i - 1], type);
EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp));
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp));
EXPECT_EQ(timestamp, last_timestamp + expected_timestamp_increment[i]);
last_timestamp = timestamp;
@@ -778,12 +756,10 @@
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
for (size_t i = 6; i < 8; ++i) {
- ASSERT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(expected_type[i - 1], type);
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp));
EXPECT_EQ(timestamp, last_timestamp + expected_timestamp_increment[i]);
last_timestamp = timestamp;
@@ -871,24 +847,23 @@
EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
- const size_t kMaxOutputSize = 10 * kSampleRateHz / 1000 * kChannels;
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
-
- EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(kMaxOutputSize, output,
- &samples_per_channel, &num_channels,
- &type));
+ // First call to GetAudio will try to decode the "faulty" packet.
+ // Expect kFail return value...
+ EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &type));
+ // ... and kOtherDecoderError error code.
EXPECT_EQ(NetEq::kOtherDecoderError, neteq_->LastError());
- EXPECT_EQ(kMaxOutputSize, samples_per_channel * kChannels);
- EXPECT_EQ(kChannels, num_channels);
+ // Output size and number of channels should be correct.
+ const size_t kExpectedOutputSize = 10 * (kSampleRateHz / 1000) * kChannels;
+ EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
+ EXPECT_EQ(kChannels, output.num_channels_);
- EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(kMaxOutputSize, output,
- &samples_per_channel, &num_channels,
- &type));
- EXPECT_EQ(kMaxOutputSize, samples_per_channel * kChannels);
- EXPECT_EQ(kChannels, num_channels);
+ // Second call to GetAudio will decode the packet that is ok. No errors are
+ // expected.
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
+ EXPECT_EQ(kChannels, output.num_channels_);
}
// This test inserts packets until the buffer is flushed. After that, it asks
@@ -978,15 +953,11 @@
// Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- ASSERT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type);
EXPECT_CALL(mock_decoder, Die());
@@ -1075,43 +1046,33 @@
// Pull audio.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type);
// Pull audio again. Decoder fails.
- EXPECT_EQ(NetEq::kFail,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
+ EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &type));
EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError());
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
// TODO(minyue): should NetEq better give kOutputPLC, since it is actually an
// expansion.
EXPECT_EQ(kOutputNormal, type);
// Pull audio again, should continue an expansion.
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputPLC, type);
// Pull audio again, should behave normal.
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputNormal, type);
EXPECT_CALL(mock_decoder, Die());
@@ -1196,35 +1157,27 @@
// Pull audio.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
- int16_t output[kMaxOutputSize];
- size_t samples_per_channel;
- size_t num_channels;
+ AudioFrame output;
NetEqOutputType type;
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputCNG, type);
// Pull audio again. Decoder fails.
- EXPECT_EQ(NetEq::kFail,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
+ EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output, &type));
EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError());
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
// TODO(minyue): should NetEq better give kOutputPLC, since it is actually an
// expansion.
EXPECT_EQ(kOutputCNG, type);
// Pull audio again, should resume codec CNG.
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
- &num_channels, &type));
- EXPECT_EQ(kMaxOutputSize, samples_per_channel);
- EXPECT_EQ(1u, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &type));
+ EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
+ EXPECT_EQ(1u, output.num_channels_);
EXPECT_EQ(kOutputCNG, type);
EXPECT_CALL(mock_decoder, Die());
diff --git a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
index f22c51b..91ae4d0 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc
@@ -13,6 +13,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/modules/include/module_common_types.h"
namespace webrtc {
namespace test {
@@ -83,7 +84,6 @@
public:
static const int kPayloadSizeByte = 30;
static const int kFrameSizeMs = 20;
- static const int kMaxOutputSize = 960; // 10 ms * 48 kHz * 2 channels.
enum logic {
kIgnore,
@@ -195,7 +195,7 @@
InsertPacket(rtp_header_, payload_, next_send_time);
}
}
- GetOutputAudio(kMaxOutputSize, output_, &output_type);
+ GetOutputAudio(&output_frame_, &output_type);
time_now += kOutputLengthMs;
}
CheckNetworkStatistics(expects);
@@ -269,7 +269,7 @@
uint32_t last_lost_time_;
uint32_t packet_loss_interval_;
uint8_t payload_[kPayloadSizeByte];
- int16_t output_[kMaxOutputSize];
+ AudioFrame output_frame_;
};
TEST(NetEqNetworkStatsTest, DecodeFec) {
diff --git a/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc
index aaff471..5beeeea 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc
@@ -20,6 +20,7 @@
#include "webrtc/modules/audio_coding/neteq/include/neteq.h"
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
@@ -69,7 +70,6 @@
input_multi_channel_ = new int16_t[frame_size_samples_ * num_channels_];
encoded_multi_channel_ = new uint8_t[frame_size_samples_ * 2 *
num_channels_];
- output_multi_channel_ = new int16_t[kMaxBlockSize * num_channels_];
}
~NetEqStereoTest() {
@@ -79,7 +79,6 @@
delete [] encoded_;
delete [] input_multi_channel_;
delete [] encoded_multi_channel_;
- delete [] output_multi_channel_;
}
virtual void SetUp() {
@@ -164,8 +163,9 @@
virtual void VerifyOutput(size_t num_samples) {
for (size_t i = 0; i < num_samples; ++i) {
for (size_t j = 0; j < num_channels_; ++j) {
- ASSERT_EQ(output_[i], output_multi_channel_[i * num_channels_ + j]) <<
- "Diff in sample " << i << ", channel " << j << ".";
+ ASSERT_EQ(output_.data_[i],
+ output_multi_channel_.data_[i * num_channels_ + j])
+ << "Diff in sample " << i << ", channel " << j << ".";
}
}
}
@@ -213,22 +213,15 @@
}
NetEqOutputType output_type;
// Get audio from mono instance.
- size_t samples_per_channel;
- size_t num_channels;
- EXPECT_EQ(NetEq::kOK,
- neteq_mono_->GetAudio(kMaxBlockSize, output_,
- &samples_per_channel, &num_channels,
- &output_type));
- EXPECT_EQ(1u, num_channels);
- EXPECT_EQ(output_size_samples_, samples_per_channel);
+ EXPECT_EQ(NetEq::kOK, neteq_mono_->GetAudio(&output_, &output_type));
+ EXPECT_EQ(1u, output_.num_channels_);
+ EXPECT_EQ(output_size_samples_, output_.samples_per_channel_);
// Get audio from multi-channel instance.
ASSERT_EQ(NetEq::kOK,
- neteq_->GetAudio(kMaxBlockSize * num_channels_,
- output_multi_channel_,
- &samples_per_channel, &num_channels,
- &output_type));
- EXPECT_EQ(num_channels_, num_channels);
- EXPECT_EQ(output_size_samples_, samples_per_channel);
+ neteq_->GetAudio(&output_multi_channel_, &output_type));
+ EXPECT_EQ(num_channels_, output_multi_channel_.num_channels_);
+ EXPECT_EQ(output_size_samples_,
+ output_multi_channel_.samples_per_channel_);
std::ostringstream ss;
ss << "Lap number " << k << ".";
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
@@ -253,8 +246,8 @@
int16_t* input_multi_channel_;
uint8_t* encoded_;
uint8_t* encoded_multi_channel_;
- int16_t output_[kMaxBlockSize];
- int16_t* output_multi_channel_;
+ AudioFrame output_;
+ AudioFrame output_multi_channel_;
WebRtcRTPHeader rtp_header_mono_;
WebRtcRTPHeader rtp_header_;
size_t payload_size_bytes_;
@@ -360,14 +353,16 @@
// TODO(hlundin): NetEq is not giving bitexact results for these cases.
virtual void VerifyOutput(size_t num_samples) {
for (size_t i = 0; i < num_samples; ++i) {
- auto first_channel_sample = output_multi_channel_[i * num_channels_];
+ auto first_channel_sample =
+ output_multi_channel_.data_[i * num_channels_];
for (size_t j = 0; j < num_channels_; ++j) {
const int kErrorMargin = 200;
- EXPECT_NEAR(output_[i], output_multi_channel_[i * num_channels_ + j],
+ EXPECT_NEAR(output_.data_[i],
+ output_multi_channel_.data_[i * num_channels_ + j],
kErrorMargin)
<< "Diff in sample " << i << ", channel " << j << ".";
EXPECT_EQ(first_channel_sample,
- output_multi_channel_[i * num_channels_ + j]);
+ output_multi_channel_.data_[i * num_channels_ + j]);
}
}
}
diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
index 0a85466..8d401a2 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
@@ -29,6 +29,7 @@
#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h"
#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/typedefs.h"
@@ -279,7 +280,6 @@
static const size_t kBlockSize16kHz = kTimeStepMs * 16;
static const size_t kBlockSize32kHz = kTimeStepMs * 32;
static const size_t kBlockSize48kHz = kTimeStepMs * 48;
- static const size_t kMaxBlockSize = kBlockSize48kHz;
static const int kInitSampleRateHz = 8000;
NetEqDecodingTest();
@@ -288,7 +288,7 @@
void SelectDecoders(NetEqDecoder* used_codec);
void LoadDecoders();
void OpenInputFile(const std::string &rtp_file);
- void Process(size_t* out_len);
+ void Process();
void DecodeAndCompare(const std::string& rtp_file,
const std::string& ref_file,
@@ -323,7 +323,7 @@
std::unique_ptr<test::RtpFileSource> rtp_source_;
std::unique_ptr<test::Packet> packet_;
unsigned int sim_clock_;
- int16_t out_data_[kMaxBlockSize];
+ AudioFrame out_frame_;
int output_sample_rate_;
int algorithmic_delay_ms_;
};
@@ -333,7 +333,6 @@
const size_t NetEqDecodingTest::kBlockSize8kHz;
const size_t NetEqDecodingTest::kBlockSize16kHz;
const size_t NetEqDecodingTest::kBlockSize32kHz;
-const size_t NetEqDecodingTest::kMaxBlockSize;
const int NetEqDecodingTest::kInitSampleRateHz;
NetEqDecodingTest::NetEqDecodingTest()
@@ -343,7 +342,6 @@
output_sample_rate_(kInitSampleRateHz),
algorithmic_delay_ms_(0) {
config_.sample_rate_hz = kInitSampleRateHz;
- memset(out_data_, 0, sizeof(out_data_));
}
void NetEqDecodingTest::SetUp() {
@@ -406,7 +404,7 @@
rtp_source_.reset(test::RtpFileSource::Create(rtp_file));
}
-void NetEqDecodingTest::Process(size_t* out_len) {
+void NetEqDecodingTest::Process() {
// Check if time to receive.
while (packet_ && sim_clock_ >= packet_->time_ms()) {
if (packet_->payload_length_bytes() > 0) {
@@ -429,14 +427,12 @@
// Get audio from NetEq.
NetEqOutputType type;
- size_t num_channels;
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, out_len,
- &num_channels, &type));
- ASSERT_TRUE((*out_len == kBlockSize8kHz) ||
- (*out_len == kBlockSize16kHz) ||
- (*out_len == kBlockSize32kHz) ||
- (*out_len == kBlockSize48kHz));
- output_sample_rate_ = static_cast<int>(*out_len / 10 * 1000);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_TRUE((out_frame_.samples_per_channel_ == kBlockSize8kHz) ||
+ (out_frame_.samples_per_channel_ == kBlockSize16kHz) ||
+ (out_frame_.samples_per_channel_ == kBlockSize32kHz) ||
+ (out_frame_.samples_per_channel_ == kBlockSize48kHz));
+ output_sample_rate_ = out_frame_.sample_rate_hz_;
EXPECT_EQ(output_sample_rate_, neteq_->last_output_sample_rate_hz());
// Increase time.
@@ -473,9 +469,9 @@
std::ostringstream ss;
ss << "Lap number " << i++ << " in DecodeAndCompare while loop";
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
- size_t out_len = 0;
- ASSERT_NO_FATAL_FAILURE(Process(&out_len));
- ASSERT_NO_FATAL_FAILURE(ref_files.ProcessReference(out_data_, out_len));
+ ASSERT_NO_FATAL_FAILURE(Process());
+ ASSERT_NO_FATAL_FAILURE(ref_files.ProcessReference(
+ out_frame_.data_, out_frame_.samples_per_channel_));
// Query the network statistics API once per second
if (sim_clock_ % 1000 == 0) {
@@ -615,12 +611,9 @@
}
// Pull out all data.
for (size_t i = 0; i < num_frames; ++i) {
- size_t out_len;
- size_t num_channels;
NetEqOutputType type;
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
NetEqNetworkStatistics stats;
@@ -660,12 +653,9 @@
}
// Pull out data once.
- size_t out_len;
- size_t num_channels;
NetEqOutputType type;
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
NetEqNetworkStatistics network_stats;
@@ -691,12 +681,9 @@
}
// Pull out data once.
- size_t out_len;
- size_t num_channels;
NetEqOutputType type;
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
NetEqNetworkStatistics network_stats;
@@ -716,8 +703,6 @@
const size_t kPayloadBytes = kSamples * 2;
double next_input_time_ms = 0.0;
double t_ms;
- size_t out_len;
- size_t num_channels;
NetEqOutputType type;
// Insert speech for 5 seconds.
@@ -735,9 +720,8 @@
next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor;
}
// Pull out data once.
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
EXPECT_EQ(kOutputNormal, type);
@@ -763,9 +747,8 @@
next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor;
}
// Pull out data once.
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
EXPECT_EQ(kOutputCNG, type);
@@ -777,10 +760,8 @@
const double loop_end_time = t_ms + network_freeze_ms;
for (; t_ms < loop_end_time; t_ms += 10) {
// Pull out data once.
- ASSERT_EQ(0,
- neteq_->GetAudio(
- kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
EXPECT_EQ(kOutputCNG, type);
}
bool pull_once = pull_audio_during_freeze;
@@ -791,11 +772,8 @@
if (pull_once && next_input_time_ms >= pull_time_ms) {
pull_once = false;
// Pull out data once.
- ASSERT_EQ(
- 0,
- neteq_->GetAudio(
- kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
EXPECT_EQ(kOutputCNG, type);
t_ms += 10;
}
@@ -828,9 +806,8 @@
next_input_time_ms += kFrameSizeMs * drift_factor;
}
// Pull out data once.
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
// Increase clock.
t_ms += 10;
}
@@ -953,14 +930,10 @@
NetEqOutputType type;
// Set all of |out_data_| to 1, and verify that it was set to 0 by the call
// to GetAudio.
- for (size_t i = 0; i < kMaxBlockSize; ++i) {
- out_data_[i] = 1;
+ for (size_t i = 0; i < AudioFrame::kMaxDataSizeSamples; ++i) {
+ out_frame_.data_[i] = 1;
}
- size_t num_channels;
- size_t samples_per_channel;
- EXPECT_EQ(NetEq::kFail,
- neteq_->GetAudio(kMaxBlockSize, out_data_,
- &samples_per_channel, &num_channels, &type));
+ EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&out_frame_, &type));
// Verify that there is a decoder error to check.
EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
@@ -980,13 +953,14 @@
std::ostringstream ss;
ss << "i = " << i;
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
- EXPECT_EQ(0, out_data_[i]);
+ EXPECT_EQ(0, out_frame_.data_[i]);
}
- for (size_t i = kExpectedOutputLength; i < kMaxBlockSize; ++i) {
+ for (size_t i = kExpectedOutputLength; i < AudioFrame::kMaxDataSizeSamples;
+ ++i) {
std::ostringstream ss;
ss << "i = " << i;
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
- EXPECT_EQ(1, out_data_[i]);
+ EXPECT_EQ(1, out_frame_.data_[i]);
}
}
@@ -994,14 +968,10 @@
NetEqOutputType type;
// Set all of |out_data_| to 1, and verify that it was set to 0 by the call
// to GetAudio.
- for (size_t i = 0; i < kMaxBlockSize; ++i) {
- out_data_[i] = 1;
+ for (size_t i = 0; i < AudioFrame::kMaxDataSizeSamples; ++i) {
+ out_frame_.data_[i] = 1;
}
- size_t num_channels;
- size_t samples_per_channel;
- EXPECT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_,
- &samples_per_channel,
- &num_channels, &type));
+ EXPECT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
// Verify that the first block of samples is set to 0.
static const int kExpectedOutputLength =
kInitSampleRateHz / 100; // 10 ms at initial sample rate.
@@ -1009,7 +979,7 @@
std::ostringstream ss;
ss << "i = " << i;
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
- EXPECT_EQ(0, out_data_[i]);
+ EXPECT_EQ(0, out_frame_.data_[i]);
}
// Verify that the sample rate did not change from the initial configuration.
EXPECT_EQ(config_.sample_rate_hz, neteq_->last_output_sample_rate_hz());
@@ -1037,7 +1007,7 @@
}
NetEqOutputType type;
- int16_t output[kBlockSize32kHz]; // Maximum size is chosen.
+ AudioFrame output;
test::AudioLoop input;
// We are using the same 32 kHz input file for all tests, regardless of
// |sampling_rate_hz|. The output may sound weird, but the test is still
@@ -1053,9 +1023,6 @@
PopulateRtpInfo(0, 0, &rtp_info);
rtp_info.header.payloadType = payload_type;
- size_t number_channels = 0;
- size_t samples_per_channel = 0;
-
uint32_t receive_timestamp = 0;
for (int n = 0; n < 10; ++n) { // Insert few packets and get audio.
auto block = input.GetNextBlock();
@@ -1064,19 +1031,13 @@
WebRtcPcm16b_Encode(block.data(), block.size(), payload);
ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2);
- number_channels = 0;
- samples_per_channel = 0;
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>(
payload, enc_len_bytes),
receive_timestamp));
- ASSERT_EQ(0,
- neteq_->GetAudio(kBlockSize32kHz,
- output,
- &samples_per_channel,
- &number_channels,
- &type));
- ASSERT_EQ(1u, number_channels);
- ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
+ output.Reset();
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(1u, output.num_channels_);
+ ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_);
ASSERT_EQ(kOutputNormal, type);
// Next packet.
@@ -1085,20 +1046,14 @@
receive_timestamp += expected_samples_per_channel;
}
- number_channels = 0;
- samples_per_channel = 0;
+ output.Reset();
// Get audio without inserting packets, expecting PLC and PLC-to-CNG. Pull
// one frame without checking speech-type. This is the first frame pulled
// without inserting any packet, and might not be labeled as PLC.
- ASSERT_EQ(0,
- neteq_->GetAudio(kBlockSize32kHz,
- output,
- &samples_per_channel,
- &number_channels,
- &type));
- ASSERT_EQ(1u, number_channels);
- ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(1u, output.num_channels_);
+ ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_);
// To be able to test the fading of background noise we need at lease to
// pull 611 frames.
@@ -1109,22 +1064,17 @@
const int kNumPlcToCngTestFrames = 20;
bool plc_to_cng = false;
for (int n = 0; n < kFadingThreshold + kNumPlcToCngTestFrames; ++n) {
- number_channels = 0;
- samples_per_channel = 0;
- memset(output, 1, sizeof(output)); // Set to non-zero.
- ASSERT_EQ(0,
- neteq_->GetAudio(kBlockSize32kHz,
- output,
- &samples_per_channel,
- &number_channels,
- &type));
- ASSERT_EQ(1u, number_channels);
- ASSERT_EQ(expected_samples_per_channel, samples_per_channel);
+ output.Reset();
+ memset(output.data_, 1, sizeof(output.data_)); // Set to non-zero.
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &type));
+ ASSERT_EQ(1u, output.num_channels_);
+ ASSERT_EQ(expected_samples_per_channel, output.samples_per_channel_);
if (type == kOutputPLCtoCNG) {
plc_to_cng = true;
double sum_squared = 0;
- for (size_t k = 0; k < number_channels * samples_per_channel; ++k)
- sum_squared += output[k] * output[k];
+ for (size_t k = 0;
+ k < output.num_channels_ * output.samples_per_channel_; ++k)
+ sum_squared += output.data_[k] * output.data_[k];
TestCondition(sum_squared, n > kFadingThreshold);
} else {
EXPECT_EQ(kOutputPLC, type);
@@ -1282,7 +1232,7 @@
PopulateRtpInfo(0, 0, &rtp_info);
const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t);
uint8_t payload[kPayloadBytes];
- int16_t decoded[kBlockSize16kHz];
+ AudioFrame output;
int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1;
for (size_t n = 0; n < kPayloadBytes; ++n) {
payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence.
@@ -1290,16 +1240,12 @@
// Insert some packets which decode to noise. We are not interested in
// actual decoded values.
NetEqOutputType output_type;
- size_t num_channels;
- size_t samples_per_channel;
uint32_t receive_timestamp = 0;
for (int n = 0; n < 100; ++n) {
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp));
- ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
- &samples_per_channel, &num_channels,
- &output_type));
- ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
- ASSERT_EQ(1u, num_channels);
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type));
+ ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_);
+ ASSERT_EQ(1u, output.num_channels_);
rtp_info.header.sequenceNumber++;
rtp_info.header.timestamp += kBlockSize16kHz;
@@ -1313,13 +1259,12 @@
// Insert sync-packets, the decoded sequence should be all-zero.
for (int n = 0; n < kNumSyncPackets; ++n) {
ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp));
- ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
- &samples_per_channel, &num_channels,
- &output_type));
- ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
- ASSERT_EQ(1u, num_channels);
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type));
+ ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_);
+ ASSERT_EQ(1u, output.num_channels_);
if (n > algorithmic_frame_delay) {
- EXPECT_TRUE(IsAllZero(decoded, samples_per_channel * num_channels));
+ EXPECT_TRUE(IsAllZero(
+ output.data_, output.samples_per_channel_ * output.num_channels_));
}
rtp_info.header.sequenceNumber++;
rtp_info.header.timestamp += kBlockSize16kHz;
@@ -1330,12 +1275,11 @@
// network statistics would show some packet loss.
for (int n = 0; n <= algorithmic_frame_delay + 10; ++n) {
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp));
- ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
- &samples_per_channel, &num_channels,
- &output_type));
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type));
if (n >= algorithmic_frame_delay + 1) {
// Expect that this frame contain samples from regular RTP.
- EXPECT_TRUE(IsAllNonZero(decoded, samples_per_channel * num_channels));
+ EXPECT_TRUE(IsAllNonZero(
+ output.data_, output.samples_per_channel_ * output.num_channels_));
}
rtp_info.header.sequenceNumber++;
rtp_info.header.timestamp += kBlockSize16kHz;
@@ -1359,24 +1303,20 @@
PopulateRtpInfo(0, 0, &rtp_info);
const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t);
uint8_t payload[kPayloadBytes];
- int16_t decoded[kBlockSize16kHz];
+ AudioFrame output;
for (size_t n = 0; n < kPayloadBytes; ++n) {
payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence.
}
// Insert some packets which decode to noise. We are not interested in
// actual decoded values.
NetEqOutputType output_type;
- size_t num_channels;
- size_t samples_per_channel;
uint32_t receive_timestamp = 0;
int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1;
for (int n = 0; n < algorithmic_frame_delay; ++n) {
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp));
- ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
- &samples_per_channel, &num_channels,
- &output_type));
- ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
- ASSERT_EQ(1u, num_channels);
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type));
+ ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_);
+ ASSERT_EQ(1u, output.num_channels_);
rtp_info.header.sequenceNumber++;
rtp_info.header.timestamp += kBlockSize16kHz;
receive_timestamp += kBlockSize16kHz;
@@ -1411,12 +1351,11 @@
// Decode.
for (int n = 0; n < kNumSyncPackets; ++n) {
- ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
- &samples_per_channel, &num_channels,
- &output_type));
- ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
- ASSERT_EQ(1u, num_channels);
- EXPECT_TRUE(IsAllNonZero(decoded, samples_per_channel * num_channels));
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type));
+ ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_);
+ ASSERT_EQ(1u, output.num_channels_);
+ EXPECT_TRUE(IsAllNonZero(
+ output.data_, output.samples_per_channel_ * output.num_channels_));
}
}
@@ -1432,10 +1371,6 @@
const int kSamples = kBlockSize16kHz * kBlocksPerFrame;
const size_t kPayloadBytes = kSamples * sizeof(int16_t);
double next_input_time_ms = 0.0;
- int16_t decoded[kBlockSize16kHz];
- size_t num_channels;
- size_t samples_per_channel;
- NetEqOutputType output_type;
uint32_t receive_timestamp = 0;
// Insert speech for 2 seconds.
@@ -1482,11 +1417,11 @@
timestamp_wrapped |= timestamp < last_timestamp;
}
// Pull out data once.
- ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded,
- &samples_per_channel, &num_channels,
- &output_type));
- ASSERT_EQ(kBlockSize16kHz, samples_per_channel);
- ASSERT_EQ(1u, num_channels);
+ AudioFrame output;
+ NetEqOutputType output_type;
+ ASSERT_EQ(0, neteq_->GetAudio(&output, &output_type));
+ ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_);
+ ASSERT_EQ(1u, output.num_channels_);
// Expect delay (in samples) to be less than 2 packets.
EXPECT_LE(timestamp - PlayoutTimestamp(),
@@ -1536,8 +1471,6 @@
algorithmic_delay_ms_ * kSampleRateKhz, 5 * kSampleRateKhz / 8);
// Insert three speech packets. Three are needed to get the frame length
// correct.
- size_t out_len;
- size_t num_channels;
NetEqOutputType type;
uint8_t payload[kPayloadBytes] = {0};
WebRtcRTPHeader rtp_info;
@@ -1548,10 +1481,8 @@
timestamp += kSamples;
// Pull audio once.
- ASSERT_EQ(0,
- neteq_->GetAudio(
- kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
// Verify speech output.
EXPECT_EQ(kOutputNormal, type);
@@ -1567,10 +1498,8 @@
rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0));
// Pull audio once and make sure CNG is played.
- ASSERT_EQ(0,
- neteq_->GetAudio(
- kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
EXPECT_EQ(kOutputCNG, type);
EXPECT_EQ(timestamp - algorithmic_delay_samples, PlayoutTimestamp());
@@ -1583,10 +1512,8 @@
// Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since
// we have already pulled out CNG once.
for (int cng_time_ms = 10; cng_time_ms < kCngPeriodMs; cng_time_ms += 10) {
- ASSERT_EQ(0,
- neteq_->GetAudio(
- kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
EXPECT_EQ(kOutputCNG, type);
EXPECT_EQ(timestamp - algorithmic_delay_samples,
PlayoutTimestamp());
@@ -1599,10 +1526,8 @@
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0));
// Pull audio once and verify that the output is speech again.
- ASSERT_EQ(0,
- neteq_->GetAudio(
- kMaxBlockSize, out_data_, &out_len, &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
EXPECT_EQ(kOutputNormal, type);
EXPECT_EQ(timestamp + kSamples - algorithmic_delay_samples,
PlayoutTimestamp());
@@ -1639,12 +1564,9 @@
timestamp += kCngPeriodSamples;
// Pull audio once and make sure CNG is played.
- size_t out_len;
- size_t num_channels;
NetEqOutputType type;
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
EXPECT_EQ(kOutputCNG, type);
// Insert some speech packets.
@@ -1655,9 +1577,8 @@
timestamp += kSamples;
// Pull audio once.
- ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len,
- &num_channels, &type));
- ASSERT_EQ(kBlockSize16kHz, out_len);
+ ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &type));
+ ASSERT_EQ(kBlockSize16kHz, out_frame_.samples_per_channel_);
}
// Verify speech output.
EXPECT_EQ(kOutputNormal, type);
diff --git a/webrtc/modules/audio_coding/neteq/sync_buffer.cc b/webrtc/modules/audio_coding/neteq/sync_buffer.cc
index d1802e1..543f78b 100644
--- a/webrtc/modules/audio_coding/neteq/sync_buffer.cc
+++ b/webrtc/modules/audio_coding/neteq/sync_buffer.cc
@@ -8,10 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include <assert.h>
-
#include <algorithm> // Access to min.
+#include "webrtc/base/checks.h"
#include "webrtc/modules/audio_coding/neteq/sync_buffer.h"
namespace webrtc {
@@ -71,16 +70,18 @@
ReplaceAtIndex(insert_this, insert_this.Size(), position);
}
-size_t SyncBuffer::GetNextAudioInterleaved(size_t requested_len,
- int16_t* output) {
- if (!output) {
- assert(false);
- return 0;
- }
- size_t samples_to_read = std::min(FutureLength(), requested_len);
- ReadInterleavedFromIndex(next_index_, samples_to_read, output);
- next_index_ += samples_to_read;
- return samples_to_read;
+void SyncBuffer::GetNextAudioInterleaved(size_t requested_len,
+ AudioFrame* output) {
+ RTC_DCHECK(output);
+ const size_t samples_to_read = std::min(FutureLength(), requested_len);
+ output->Reset();
+ const size_t tot_samples_read =
+ ReadInterleavedFromIndex(next_index_, samples_to_read, output->data_);
+ const size_t samples_read_per_channel = tot_samples_read / Channels();
+ next_index_ += samples_read_per_channel;
+ output->interleaved_ = true;
+ output->num_channels_ = Channels();
+ output->samples_per_channel_ = samples_read_per_channel;
}
void SyncBuffer::IncreaseEndTimestamp(uint32_t increment) {
diff --git a/webrtc/modules/audio_coding/neteq/sync_buffer.h b/webrtc/modules/audio_coding/neteq/sync_buffer.h
index 38e7887..c3bb4a9 100644
--- a/webrtc/modules/audio_coding/neteq/sync_buffer.h
+++ b/webrtc/modules/audio_coding/neteq/sync_buffer.h
@@ -13,6 +13,7 @@
#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/typedefs.h"
namespace webrtc {
@@ -65,8 +66,10 @@
// Reads |requested_len| samples from each channel and writes them interleaved
// into |output|. The |next_index_| is updated to point to the sample to read
- // next time.
- size_t GetNextAudioInterleaved(size_t requested_len, int16_t* output);
+ // next time. The AudioFrame |output| is first reset, and the |data_|,
+ // |interleaved_|, |num_channels_|, and |samples_per_channel_| fields are
+ // updated.
+ void GetNextAudioInterleaved(size_t requested_len, AudioFrame* output);
// Adds |increment| to |end_timestamp_|.
void IncreaseEndTimestamp(uint32_t increment);
diff --git a/webrtc/modules/audio_coding/neteq/sync_buffer_unittest.cc b/webrtc/modules/audio_coding/neteq/sync_buffer_unittest.cc
index 332ec2f..0f7b989 100644
--- a/webrtc/modules/audio_coding/neteq/sync_buffer_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/sync_buffer_unittest.cc
@@ -140,20 +140,29 @@
// Read to interleaved output. Read in two batches, where each read operation
// should automatically update the |net_index_| in the SyncBuffer.
- int16_t output[kChannels * kNewLen];
// Note that |samples_read| is the number of samples read from each channel.
// That is, the number of samples written to |output| is
// |samples_read| * |kChannels|.
- size_t samples_read = sync_buffer.GetNextAudioInterleaved(kNewLen / 2,
- output);
- samples_read +=
- sync_buffer.GetNextAudioInterleaved(kNewLen / 2,
- &output[samples_read * kChannels]);
- EXPECT_EQ(kNewLen, samples_read);
+ AudioFrame output1;
+ sync_buffer.GetNextAudioInterleaved(kNewLen / 2, &output1);
+ EXPECT_EQ(kChannels, output1.num_channels_);
+ EXPECT_EQ(kNewLen / 2, output1.samples_per_channel_);
+
+ AudioFrame output2;
+ sync_buffer.GetNextAudioInterleaved(kNewLen / 2, &output2);
+ EXPECT_EQ(kChannels, output2.num_channels_);
+ EXPECT_EQ(kNewLen / 2, output2.samples_per_channel_);
// Verify the data.
- int16_t* output_ptr = output;
- for (size_t i = 0; i < kNewLen; ++i) {
+ int16_t* output_ptr = output1.data_;
+ for (size_t i = 0; i < kNewLen / 2; ++i) {
+ for (size_t channel = 0; channel < kChannels; ++channel) {
+ EXPECT_EQ(new_data[channel][i], *output_ptr);
+ ++output_ptr;
+ }
+ }
+ output_ptr = output2.data_;
+ for (size_t i = kNewLen / 2; i < kNewLen; ++i) {
for (size_t channel = 0; channel < kChannels; ++channel) {
EXPECT_EQ(new_data[channel][i], *output_ptr);
++output_ptr;
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc
index 694b9ed..94436e1 100644
--- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc
@@ -43,23 +43,14 @@
neteq_->InsertPacket(rtp_header, payload, receive_timestamp));
}
-size_t NetEqExternalDecoderTest::GetOutputAudio(size_t max_length,
- int16_t* output,
- NetEqOutputType* output_type) {
+void NetEqExternalDecoderTest::GetOutputAudio(AudioFrame* output,
+ NetEqOutputType* output_type) {
// Get audio from regular instance.
- size_t samples_per_channel;
- size_t num_channels;
- EXPECT_EQ(NetEq::kOK,
- neteq_->GetAudio(max_length,
- output,
- &samples_per_channel,
- &num_channels,
- output_type));
- EXPECT_EQ(channels_, num_channels);
+ EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(output, output_type));
+ EXPECT_EQ(channels_, output->num_channels_);
EXPECT_EQ(static_cast<size_t>(kOutputLengthMs * sample_rate_hz_ / 1000),
- samples_per_channel);
+ output->samples_per_channel_);
EXPECT_EQ(sample_rate_hz_, neteq_->last_output_sample_rate_hz());
- return samples_per_channel;
}
} // namespace test
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h
index 1b36d8b..bd9f01a 100644
--- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h
@@ -42,10 +42,8 @@
rtc::ArrayView<const uint8_t> payload,
uint32_t receive_timestamp);
- // Get 10 ms of audio data. The data is written to |output|, which can hold
- // (at least) |max_length| elements. Returns number of samples.
- size_t GetOutputAudio(size_t max_length, int16_t* output,
- NetEqOutputType* output_type);
+ // Get 10 ms of audio data.
+ void GetOutputAudio(AudioFrame* output, NetEqOutputType* output_type);
NetEq* neteq() { return neteq_.get(); }
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc
index 7d1f9f9..f1577df 100644
--- a/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc
@@ -14,6 +14,7 @@
#include "webrtc/modules/audio_coding/neteq/include/neteq.h"
#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/typedefs.h"
@@ -103,21 +104,15 @@
}
// Get output audio, but don't do anything with it.
- static const int kMaxChannels = 1;
- static const size_t kMaxSamplesPerMs = 48000 / 1000;
- static const int kOutputBlockSizeMs = 10;
- static const size_t kOutDataLen =
- kOutputBlockSizeMs * kMaxSamplesPerMs * kMaxChannels;
- int16_t out_data[kOutDataLen];
- size_t num_channels;
- size_t samples_per_channel;
- int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel,
- &num_channels, NULL);
+ AudioFrame out_frame;
+ int error = neteq->GetAudio(&out_frame, NULL);
if (error != NetEq::kOK)
return -1;
- assert(samples_per_channel == static_cast<size_t>(kSampRateHz * 10 / 1000));
+ assert(out_frame.samples_per_channel_ ==
+ static_cast<size_t>(kSampRateHz * 10 / 1000));
+ static const int kOutputBlockSizeMs = 10;
time_now_ms += kOutputBlockSizeMs;
if (time_now_ms >= runtime_ms / 2 && !drift_flipped) {
// Apply negative drift second half of simulation.
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc
index 7118f4e..1155987 100644
--- a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc
@@ -220,7 +220,6 @@
out_sampling_khz_(out_sampling_khz),
in_size_samples_(
static_cast<size_t>(in_sampling_khz_ * block_duration_ms_)),
- out_size_samples_(static_cast<size_t>(out_sampling_khz_ * kOutputSizeMs)),
payload_size_bytes_(0),
max_payload_bytes_(0),
in_file_(new ResampleInputAudioFile(FLAGS_in_filename,
@@ -249,7 +248,6 @@
neteq_.reset(NetEq::Create(config));
max_payload_bytes_ = in_size_samples_ * channels_ * sizeof(int16_t);
in_data_.reset(new int16_t[in_size_samples_ * channels_]);
- out_data_.reset(new int16_t[out_size_samples_ * channels_]);
}
NetEqQualityTest::~NetEqQualityTest() {
@@ -393,18 +391,18 @@
}
int NetEqQualityTest::DecodeBlock() {
- size_t channels;
- size_t samples;
- int ret = neteq_->GetAudio(out_size_samples_ * channels_, &out_data_[0],
- &samples, &channels, NULL);
+ int ret = neteq_->GetAudio(&out_frame_, NULL);
if (ret != NetEq::kOK) {
return -1;
} else {
- assert(channels == channels_);
- assert(samples == static_cast<size_t>(kOutputSizeMs * out_sampling_khz_));
- RTC_CHECK(output_->WriteArray(out_data_.get(), samples * channels));
- return static_cast<int>(samples);
+ RTC_DCHECK_EQ(out_frame_.num_channels_, channels_);
+ RTC_DCHECK_EQ(out_frame_.samples_per_channel_,
+ static_cast<size_t>(kOutputSizeMs * out_sampling_khz_));
+ RTC_CHECK(output_->WriteArray(
+ out_frame_.data_,
+ out_frame_.samples_per_channel_ * out_frame_.num_channels_));
+ return static_cast<int>(out_frame_.samples_per_channel_);
}
}
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h
index 43c95b8..11afe68 100644
--- a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h
@@ -19,6 +19,7 @@
#include "webrtc/modules/audio_coding/neteq/tools/audio_sink.h"
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/typedefs.h"
using google::RegisterFlagValidator;
@@ -113,9 +114,6 @@
// Number of samples per channel in a frame.
const size_t in_size_samples_;
- // Expected output number of samples per channel in a frame.
- const size_t out_size_samples_;
-
size_t payload_size_bytes_;
size_t max_payload_bytes_;
@@ -129,7 +127,7 @@
std::unique_ptr<int16_t[]> in_data_;
rtc::Buffer payload_;
- std::unique_ptr<int16_t[]> out_data_;
+ AudioFrame out_frame_;
WebRtcRTPHeader rtp_header_;
size_t total_payload_size_bytes_;
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
index 1701c47..a339199 100644
--- a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -382,8 +382,6 @@
} // namespace
int main(int argc, char* argv[]) {
- static const int kMaxChannels = 5;
- static const size_t kMaxSamplesPerMs = 48000 / 1000;
static const int kOutputBlockSizeMs = 10;
std::string program_name = argv[0];
@@ -606,26 +604,19 @@
// Check if it is time to get output audio.
while (time_now_ms >= next_output_time_ms && output_event_available) {
- static const size_t kOutDataLen =
- kOutputBlockSizeMs * kMaxSamplesPerMs * kMaxChannels;
- int16_t out_data[kOutDataLen];
- size_t num_channels;
- size_t samples_per_channel;
- int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel,
- &num_channels, NULL);
+ webrtc::AudioFrame out_frame;
+ int error = neteq->GetAudio(&out_frame, NULL);
if (error != NetEq::kOK) {
std::cerr << "GetAudio returned error code " <<
neteq->LastError() << std::endl;
} else {
- // Calculate sample rate from output size.
- sample_rate_hz = rtc::checked_cast<int>(
- 1000 * samples_per_channel / kOutputBlockSizeMs);
+ sample_rate_hz = out_frame.sample_rate_hz_;
}
// Write to file.
// TODO(hlundin): Make writing to file optional.
- size_t write_len = samples_per_channel * num_channels;
- if (!output->WriteArray(out_data, write_len)) {
+ if (!output->WriteArray(out_frame.data_, out_frame.samples_per_channel_ *
+ out_frame.num_channels_)) {
std::cerr << "Error while writing to file" << std::endl;
webrtc::Trace::ReturnTrace();
exit(1);