2013-01-29 12:09:21 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-10-29 11:31:02 +01:00
|
|
|
#include "webrtc/modules/audio_coding/neteq/include/neteq.h"
|
2014-06-09 08:10:28 +00:00
|
|
|
#include "webrtc/modules/audio_coding/neteq/neteq_impl.h"
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2014-09-04 09:55:40 +00:00
|
|
|
#include "testing/gmock/include/gmock/gmock.h"
|
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
Revert of Safe numeric library: base/numerics (copied from Chromium) (patchset #11 id:250001 of https://codereview.webrtc.org/1753293002/ )
Reason for revert:
Looks like the Chrome iOS build is broken because of these two changes. So I'm going to have to revert. Here's the error:
https://build.chromium.org/p/tryserver.chromium.mac/builders/ios_rel_device_ninja/builds/185624/steps/compile/logs/stdio
FAILED: rm -f arch/libsafe_numerics.arm64.a && ./gyp-mac-tool filter-libtool libtool -static -o arch/libsafe_numerics.arm64.a
error: /Applications/Xcode7.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: no files specified
Usage: /Applications/Xcode7.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
Usage: /Applications/Xcode7.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]
FAILED: rm -f arch/libsafe_numerics.armv7.a && ./gyp-mac-tool filter-libtool libtool -static -o arch/libsafe_numerics.armv7.a
error: /Applications/Xcode7.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: no files specified
Usage: /Applications/Xcode7.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
Usage: /Applications/Xcode7.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]
ninja: build stopped: subcommand failed.
Original issue's description:
> Safe numeric library added: base/numerics (copied from Chromium)
>
> This copies the contents (unittest excluded) of base/numerics in
> chromium to base/numerics in webrtc. Files added:
> - safe_conversions.h
> - safe_conversions_impl.h
> - safe_math.h
> - safe_math_impl.h
>
> A really old version of safe_conversions[_impl].h previously existed in
> base/, this has been deleted and sources using it have been updated
> to include the new base/numerics/safe_converions.h.
>
> This CL also adds a DEPS file to webrtc/base.
>
> NOPRESUBMIT=True
> BUG=webrtc:5548, webrtc:5623
>
> Committed: https://crrev.com/de1c81b2d2196be611674aa6019b9db3a9329042
> Cr-Commit-Position: refs/heads/master@{#11907}
TBR=kjellander@webrtc.org,kwiberg@webrtc.org,tina.legrand@webrtc.org,hbos@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:5548, webrtc:5623
Review URL: https://codereview.webrtc.org/1792613002 .
Cr-Commit-Position: refs/heads/master@{#11965}
2016-03-11 17:12:32 -08:00
|
|
|
#include "webrtc/base/safe_conversions.h"
|
2014-06-09 08:10:28 +00:00
|
|
|
#include "webrtc/modules/audio_coding/neteq/accelerate.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/expand.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_buffer_level_filter.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_delay_manager.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_delay_peak_detector.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_dtmf_buffer.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_dtmf_tone_generator.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_packet_buffer.h"
|
|
|
|
|
#include "webrtc/modules/audio_coding/neteq/mock/mock_payload_splitter.h"
|
|
|
|
|
#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"
|
2016-03-04 10:34:21 -08:00
|
|
|
#include "webrtc/modules/include/module_common_types.h"
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2015-03-16 12:30:37 +00:00
|
|
|
using ::testing::AtLeast;
|
2013-01-29 12:09:21 +00:00
|
|
|
using ::testing::Return;
|
|
|
|
|
using ::testing::ReturnNull;
|
|
|
|
|
using ::testing::_;
|
|
|
|
|
using ::testing::SetArgPointee;
|
2014-11-04 14:03:58 +00:00
|
|
|
using ::testing::SetArrayArgument;
|
2013-01-29 12:09:21 +00:00
|
|
|
using ::testing::InSequence;
|
|
|
|
|
using ::testing::Invoke;
|
|
|
|
|
using ::testing::WithArg;
|
2014-11-04 14:03:58 +00:00
|
|
|
using ::testing::Pointee;
|
2014-12-09 10:46:39 +00:00
|
|
|
using ::testing::IsNull;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
|
|
|
|
// This function is called when inserting a packet list into the mock packet
|
|
|
|
|
// buffer. The purpose is to delete all inserted packets properly, to avoid
|
|
|
|
|
// memory leaks in the test.
|
|
|
|
|
int DeletePacketsAndReturnOk(PacketList* packet_list) {
|
|
|
|
|
PacketBuffer::DeleteAllPackets(packet_list);
|
|
|
|
|
return PacketBuffer::kOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class NetEqImplTest : public ::testing::Test {
|
|
|
|
|
protected:
|
2014-03-12 05:55:10 +00:00
|
|
|
NetEqImplTest()
|
|
|
|
|
: neteq_(NULL),
|
2014-04-14 18:49:17 +00:00
|
|
|
config_(),
|
2016-04-25 10:11:38 -07:00
|
|
|
tick_timer_(new TickTimer),
|
2014-03-12 05:55:10 +00:00
|
|
|
mock_buffer_level_filter_(NULL),
|
|
|
|
|
buffer_level_filter_(NULL),
|
|
|
|
|
use_mock_buffer_level_filter_(true),
|
|
|
|
|
mock_decoder_database_(NULL),
|
|
|
|
|
decoder_database_(NULL),
|
|
|
|
|
use_mock_decoder_database_(true),
|
|
|
|
|
mock_delay_peak_detector_(NULL),
|
|
|
|
|
delay_peak_detector_(NULL),
|
|
|
|
|
use_mock_delay_peak_detector_(true),
|
|
|
|
|
mock_delay_manager_(NULL),
|
|
|
|
|
delay_manager_(NULL),
|
|
|
|
|
use_mock_delay_manager_(true),
|
|
|
|
|
mock_dtmf_buffer_(NULL),
|
|
|
|
|
dtmf_buffer_(NULL),
|
|
|
|
|
use_mock_dtmf_buffer_(true),
|
|
|
|
|
mock_dtmf_tone_generator_(NULL),
|
|
|
|
|
dtmf_tone_generator_(NULL),
|
|
|
|
|
use_mock_dtmf_tone_generator_(true),
|
|
|
|
|
mock_packet_buffer_(NULL),
|
|
|
|
|
packet_buffer_(NULL),
|
|
|
|
|
use_mock_packet_buffer_(true),
|
|
|
|
|
mock_payload_splitter_(NULL),
|
|
|
|
|
payload_splitter_(NULL),
|
|
|
|
|
use_mock_payload_splitter_(true),
|
2014-04-14 18:49:17 +00:00
|
|
|
timestamp_scaler_(NULL) {
|
|
|
|
|
config_.sample_rate_hz = 8000;
|
|
|
|
|
}
|
2014-03-12 05:55:10 +00:00
|
|
|
|
|
|
|
|
void CreateInstance() {
|
|
|
|
|
if (use_mock_buffer_level_filter_) {
|
|
|
|
|
mock_buffer_level_filter_ = new MockBufferLevelFilter;
|
|
|
|
|
buffer_level_filter_ = mock_buffer_level_filter_;
|
|
|
|
|
} else {
|
|
|
|
|
buffer_level_filter_ = new BufferLevelFilter;
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_decoder_database_) {
|
|
|
|
|
mock_decoder_database_ = new MockDecoderDatabase;
|
|
|
|
|
EXPECT_CALL(*mock_decoder_database_, GetActiveCngDecoder())
|
|
|
|
|
.WillOnce(ReturnNull());
|
|
|
|
|
decoder_database_ = mock_decoder_database_;
|
|
|
|
|
} else {
|
|
|
|
|
decoder_database_ = new DecoderDatabase;
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_delay_peak_detector_) {
|
|
|
|
|
mock_delay_peak_detector_ = new MockDelayPeakDetector;
|
|
|
|
|
EXPECT_CALL(*mock_delay_peak_detector_, Reset()).Times(1);
|
|
|
|
|
delay_peak_detector_ = mock_delay_peak_detector_;
|
|
|
|
|
} else {
|
|
|
|
|
delay_peak_detector_ = new DelayPeakDetector;
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_delay_manager_) {
|
2014-04-28 08:20:04 +00:00
|
|
|
mock_delay_manager_ = new MockDelayManager(config_.max_packets_in_buffer,
|
2014-03-12 05:55:10 +00:00
|
|
|
delay_peak_detector_);
|
|
|
|
|
EXPECT_CALL(*mock_delay_manager_, set_streaming_mode(false)).Times(1);
|
|
|
|
|
delay_manager_ = mock_delay_manager_;
|
|
|
|
|
} else {
|
|
|
|
|
delay_manager_ =
|
2014-04-28 08:20:04 +00:00
|
|
|
new DelayManager(config_.max_packets_in_buffer, delay_peak_detector_);
|
2014-03-12 05:55:10 +00:00
|
|
|
}
|
|
|
|
|
if (use_mock_dtmf_buffer_) {
|
2014-04-14 18:49:17 +00:00
|
|
|
mock_dtmf_buffer_ = new MockDtmfBuffer(config_.sample_rate_hz);
|
2014-03-12 05:55:10 +00:00
|
|
|
dtmf_buffer_ = mock_dtmf_buffer_;
|
|
|
|
|
} else {
|
2014-04-14 18:49:17 +00:00
|
|
|
dtmf_buffer_ = new DtmfBuffer(config_.sample_rate_hz);
|
2014-03-12 05:55:10 +00:00
|
|
|
}
|
|
|
|
|
if (use_mock_dtmf_tone_generator_) {
|
|
|
|
|
mock_dtmf_tone_generator_ = new MockDtmfToneGenerator;
|
|
|
|
|
dtmf_tone_generator_ = mock_dtmf_tone_generator_;
|
|
|
|
|
} else {
|
|
|
|
|
dtmf_tone_generator_ = new DtmfToneGenerator;
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_packet_buffer_) {
|
2014-04-28 08:20:04 +00:00
|
|
|
mock_packet_buffer_ = new MockPacketBuffer(config_.max_packets_in_buffer);
|
2014-03-12 05:55:10 +00:00
|
|
|
packet_buffer_ = mock_packet_buffer_;
|
|
|
|
|
} else {
|
2014-04-28 08:20:04 +00:00
|
|
|
packet_buffer_ = new PacketBuffer(config_.max_packets_in_buffer);
|
2014-03-12 05:55:10 +00:00
|
|
|
}
|
|
|
|
|
if (use_mock_payload_splitter_) {
|
|
|
|
|
mock_payload_splitter_ = new MockPayloadSplitter;
|
|
|
|
|
payload_splitter_ = mock_payload_splitter_;
|
|
|
|
|
} else {
|
|
|
|
|
payload_splitter_ = new PayloadSplitter;
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
timestamp_scaler_ = new TimestampScaler(*decoder_database_);
|
2014-01-14 10:18:45 +00:00
|
|
|
AccelerateFactory* accelerate_factory = new AccelerateFactory;
|
|
|
|
|
ExpandFactory* expand_factory = new ExpandFactory;
|
|
|
|
|
PreemptiveExpandFactory* preemptive_expand_factory =
|
|
|
|
|
new PreemptiveExpandFactory;
|
|
|
|
|
|
2016-04-25 10:11:38 -07:00
|
|
|
neteq_ = new NetEqImpl(
|
|
|
|
|
config_, std::unique_ptr<TickTimer>(tick_timer_), buffer_level_filter_,
|
|
|
|
|
decoder_database_, delay_manager_, delay_peak_detector_, dtmf_buffer_,
|
|
|
|
|
dtmf_tone_generator_, packet_buffer_, payload_splitter_,
|
|
|
|
|
timestamp_scaler_, accelerate_factory, expand_factory,
|
|
|
|
|
preemptive_expand_factory);
|
2014-03-12 05:55:10 +00:00
|
|
|
ASSERT_TRUE(neteq_ != NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UseNoMocks() {
|
|
|
|
|
ASSERT_TRUE(neteq_ == NULL) << "Must call UseNoMocks before CreateInstance";
|
|
|
|
|
use_mock_buffer_level_filter_ = false;
|
|
|
|
|
use_mock_decoder_database_ = false;
|
|
|
|
|
use_mock_delay_peak_detector_ = false;
|
|
|
|
|
use_mock_delay_manager_ = false;
|
|
|
|
|
use_mock_dtmf_buffer_ = false;
|
|
|
|
|
use_mock_dtmf_tone_generator_ = false;
|
|
|
|
|
use_mock_packet_buffer_ = false;
|
|
|
|
|
use_mock_payload_splitter_ = false;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~NetEqImplTest() {
|
2014-03-12 05:55:10 +00:00
|
|
|
if (use_mock_buffer_level_filter_) {
|
|
|
|
|
EXPECT_CALL(*mock_buffer_level_filter_, Die()).Times(1);
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_decoder_database_) {
|
|
|
|
|
EXPECT_CALL(*mock_decoder_database_, Die()).Times(1);
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_delay_manager_) {
|
|
|
|
|
EXPECT_CALL(*mock_delay_manager_, Die()).Times(1);
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_delay_peak_detector_) {
|
|
|
|
|
EXPECT_CALL(*mock_delay_peak_detector_, Die()).Times(1);
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_dtmf_buffer_) {
|
|
|
|
|
EXPECT_CALL(*mock_dtmf_buffer_, Die()).Times(1);
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_dtmf_tone_generator_) {
|
|
|
|
|
EXPECT_CALL(*mock_dtmf_tone_generator_, Die()).Times(1);
|
|
|
|
|
}
|
|
|
|
|
if (use_mock_packet_buffer_) {
|
|
|
|
|
EXPECT_CALL(*mock_packet_buffer_, Die()).Times(1);
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
delete neteq_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NetEqImpl* neteq_;
|
2014-04-14 18:49:17 +00:00
|
|
|
NetEq::Config config_;
|
2016-04-25 10:11:38 -07:00
|
|
|
TickTimer* tick_timer_;
|
2014-03-12 05:55:10 +00:00
|
|
|
MockBufferLevelFilter* mock_buffer_level_filter_;
|
|
|
|
|
BufferLevelFilter* buffer_level_filter_;
|
|
|
|
|
bool use_mock_buffer_level_filter_;
|
|
|
|
|
MockDecoderDatabase* mock_decoder_database_;
|
|
|
|
|
DecoderDatabase* decoder_database_;
|
|
|
|
|
bool use_mock_decoder_database_;
|
|
|
|
|
MockDelayPeakDetector* mock_delay_peak_detector_;
|
|
|
|
|
DelayPeakDetector* delay_peak_detector_;
|
|
|
|
|
bool use_mock_delay_peak_detector_;
|
|
|
|
|
MockDelayManager* mock_delay_manager_;
|
|
|
|
|
DelayManager* delay_manager_;
|
|
|
|
|
bool use_mock_delay_manager_;
|
|
|
|
|
MockDtmfBuffer* mock_dtmf_buffer_;
|
|
|
|
|
DtmfBuffer* dtmf_buffer_;
|
|
|
|
|
bool use_mock_dtmf_buffer_;
|
|
|
|
|
MockDtmfToneGenerator* mock_dtmf_tone_generator_;
|
|
|
|
|
DtmfToneGenerator* dtmf_tone_generator_;
|
|
|
|
|
bool use_mock_dtmf_tone_generator_;
|
|
|
|
|
MockPacketBuffer* mock_packet_buffer_;
|
|
|
|
|
PacketBuffer* packet_buffer_;
|
|
|
|
|
bool use_mock_packet_buffer_;
|
|
|
|
|
MockPayloadSplitter* mock_payload_splitter_;
|
|
|
|
|
PayloadSplitter* payload_splitter_;
|
|
|
|
|
bool use_mock_payload_splitter_;
|
2013-01-29 12:09:21 +00:00
|
|
|
TimestampScaler* timestamp_scaler_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This tests the interface class NetEq.
|
|
|
|
|
// TODO(hlundin): Move to separate file?
|
|
|
|
|
TEST(NetEq, CreateAndDestroy) {
|
2014-04-14 18:49:17 +00:00
|
|
|
NetEq::Config config;
|
|
|
|
|
NetEq* neteq = NetEq::Create(config);
|
2013-01-29 12:09:21 +00:00
|
|
|
delete neteq;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NetEqImplTest, RegisterPayloadType) {
|
2014-03-12 05:55:10 +00:00
|
|
|
CreateInstance();
|
2013-01-29 12:09:21 +00:00
|
|
|
uint8_t rtp_payload_type = 0;
|
2015-10-29 06:20:28 -07:00
|
|
|
NetEqDecoder codec_type = NetEqDecoder::kDecoderPCMu;
|
2015-12-09 06:20:58 -08:00
|
|
|
const std::string kCodecName = "Robert\'); DROP TABLE Students;";
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_,
|
2015-12-09 06:20:58 -08:00
|
|
|
RegisterPayload(rtp_payload_type, codec_type, kCodecName));
|
|
|
|
|
neteq_->RegisterPayloadType(codec_type, kCodecName, rtp_payload_type);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NetEqImplTest, RemovePayloadType) {
|
2014-03-12 05:55:10 +00:00
|
|
|
CreateInstance();
|
2013-01-29 12:09:21 +00:00
|
|
|
uint8_t rtp_payload_type = 0;
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, Remove(rtp_payload_type))
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillOnce(Return(DecoderDatabase::kDecoderNotFound));
|
|
|
|
|
// Check that kFail is returned when database returns kDecoderNotFound.
|
|
|
|
|
EXPECT_EQ(NetEq::kFail, neteq_->RemovePayloadType(rtp_payload_type));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(NetEqImplTest, InsertPacket) {
|
2014-03-12 05:55:10 +00:00
|
|
|
CreateInstance();
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
const size_t kPayloadLength = 100;
|
2013-01-29 12:09:21 +00:00
|
|
|
const uint8_t kPayloadType = 0;
|
|
|
|
|
const uint16_t kFirstSequenceNumber = 0x1234;
|
|
|
|
|
const uint32_t kFirstTimestamp = 0x12345678;
|
|
|
|
|
const uint32_t kSsrc = 0x87654321;
|
|
|
|
|
const uint32_t kFirstReceiveTime = 17;
|
|
|
|
|
uint8_t payload[kPayloadLength] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = kFirstSequenceNumber;
|
|
|
|
|
rtp_header.header.timestamp = kFirstTimestamp;
|
|
|
|
|
rtp_header.header.ssrc = kSsrc;
|
|
|
|
|
|
|
|
|
|
// Create a mock decoder object.
|
|
|
|
|
MockAudioDecoder mock_decoder;
|
2015-03-18 09:47:08 +00:00
|
|
|
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
|
2013-01-29 12:09:21 +00:00
|
|
|
// BWE update function called with first packet.
|
|
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_,
|
|
|
|
|
kPayloadLength,
|
|
|
|
|
kFirstSequenceNumber,
|
|
|
|
|
kFirstTimestamp,
|
|
|
|
|
kFirstReceiveTime));
|
|
|
|
|
// BWE update function called with second packet.
|
|
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_,
|
|
|
|
|
kPayloadLength,
|
|
|
|
|
kFirstSequenceNumber + 1,
|
|
|
|
|
kFirstTimestamp + 160,
|
|
|
|
|
kFirstReceiveTime + 155));
|
|
|
|
|
EXPECT_CALL(mock_decoder, Die()).Times(1); // Called when deleted.
|
|
|
|
|
|
|
|
|
|
// Expectations for decoder database.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, IsRed(kPayloadType))
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillRepeatedly(Return(false)); // This is not RED.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, CheckPayloadTypes(_))
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(Return(DecoderDatabase::kOK)); // Payload type is valid.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, IsDtmf(kPayloadType))
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillRepeatedly(Return(false)); // This is not DTMF.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, GetDecoder(kPayloadType))
|
2013-10-01 22:01:09 +00:00
|
|
|
.Times(3)
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillRepeatedly(Return(&mock_decoder));
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, IsComfortNoise(kPayloadType))
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillRepeatedly(Return(false)); // This is not CNG.
|
2016-04-19 05:03:45 -07:00
|
|
|
DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu, "", 8000,
|
|
|
|
|
nullptr);
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_decoder_database_, GetDecoderInfo(kPayloadType))
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillRepeatedly(Return(&info));
|
|
|
|
|
|
|
|
|
|
// Expectations for packet buffer.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_packet_buffer_, NumPacketsInBuffer())
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillOnce(Return(0)) // First packet.
|
|
|
|
|
.WillOnce(Return(1)) // Second packet.
|
|
|
|
|
.WillOnce(Return(2)); // Second packet, checking after it was inserted.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_packet_buffer_, Empty())
|
|
|
|
|
.WillOnce(Return(false)); // Called once after first packet is inserted.
|
|
|
|
|
EXPECT_CALL(*mock_packet_buffer_, Flush())
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(1);
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_packet_buffer_, InsertPacketList(_, _, _, _))
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(DoAll(SetArgPointee<2>(kPayloadType),
|
|
|
|
|
WithArg<0>(Invoke(DeletePacketsAndReturnOk))));
|
|
|
|
|
// SetArgPointee<2>(kPayloadType) means that the third argument (zero-based
|
|
|
|
|
// index) is a pointer, and the variable pointed to is set to kPayloadType.
|
|
|
|
|
// Also invoke the function DeletePacketsAndReturnOk to properly delete all
|
|
|
|
|
// packets in the list (to avoid memory leaks in the test).
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_packet_buffer_, NextRtpHeader())
|
2013-10-01 22:01:09 +00:00
|
|
|
.Times(1)
|
|
|
|
|
.WillOnce(Return(&rtp_header.header));
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Expectations for DTMF buffer.
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_dtmf_buffer_, Flush())
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(1);
|
|
|
|
|
|
|
|
|
|
// Expectations for delay manager.
|
|
|
|
|
{
|
|
|
|
|
// All expectations within this block must be called in this specific order.
|
|
|
|
|
InSequence sequence; // Dummy variable.
|
|
|
|
|
// Expectations when the first packet is inserted.
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_CALL(*mock_delay_manager_,
|
|
|
|
|
LastDecoderType(NetEqDecoder::kDecoderPCMu))
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(1);
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_delay_manager_, last_pack_cng_or_dtmf())
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(Return(-1));
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_delay_manager_, set_last_pack_cng_or_dtmf(0))
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(1);
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_delay_manager_, ResetPacketIatCount()).Times(1);
|
2013-01-29 12:09:21 +00:00
|
|
|
// Expectations when the second packet is inserted. Slightly different.
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_CALL(*mock_delay_manager_,
|
|
|
|
|
LastDecoderType(NetEqDecoder::kDecoderPCMu))
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(1);
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_delay_manager_, last_pack_cng_or_dtmf())
|
|
|
|
|
.WillOnce(Return(0));
|
|
|
|
|
EXPECT_CALL(*mock_delay_manager_, SetPacketAudioLength(30))
|
2013-01-29 12:09:21 +00:00
|
|
|
.WillOnce(Return(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Expectations for payload splitter.
|
2016-04-26 06:19:18 -07:00
|
|
|
EXPECT_CALL(*mock_payload_splitter_, SplitFec(_, _))
|
|
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(Return(PayloadSplitter::kOK));
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_CALL(*mock_payload_splitter_, SplitAudio(_, _))
|
2013-01-29 12:09:21 +00:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(Return(PayloadSplitter::kOK));
|
|
|
|
|
|
|
|
|
|
// Insert first packet.
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kFirstReceiveTime);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Insert second packet.
|
|
|
|
|
rtp_header.header.timestamp += 160;
|
|
|
|
|
rtp_header.header.sequenceNumber += 1;
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kFirstReceiveTime + 155);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2014-03-12 05:55:10 +00:00
|
|
|
TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const int kPayloadLengthSamples = 80;
|
|
|
|
|
const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterPayloadType(
|
2015-12-09 06:20:58 -08:00
|
|
|
NetEqDecoder::kDecoderPCM16B, "", kPayloadType));
|
2014-03-12 05:55:10 +00:00
|
|
|
|
|
|
|
|
// Insert packets. The buffer should not flush.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
|
2014-03-12 05:55:10 +00:00
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-03-12 05:55:10 +00:00
|
|
|
rtp_header.header.timestamp += kPayloadLengthSamples;
|
|
|
|
|
rtp_header.header.sequenceNumber += 1;
|
|
|
|
|
EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Insert one more packet and make sure the buffer got flushed. That is, it
|
|
|
|
|
// should only hold one single packet.
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
|
2014-03-12 05:55:10 +00:00
|
|
|
const RTPHeader* test_header = packet_buffer_->NextRtpHeader();
|
|
|
|
|
EXPECT_EQ(rtp_header.header.timestamp, test_header->timestamp);
|
|
|
|
|
EXPECT_EQ(rtp_header.header.sequenceNumber, test_header->sequenceNumber);
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-07 21:21:45 +00:00
|
|
|
// This test verifies that timestamps propagate from the incoming packets
|
|
|
|
|
// through to the sync buffer and to the playout timestamp.
|
|
|
|
|
TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kPayloadLengthSamples =
|
|
|
|
|
static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
|
2014-04-07 21:21:45 +00:00
|
|
|
const size_t kPayloadLengthBytes = kPayloadLengthSamples;
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// This is a dummy decoder that produces as many output samples as the input
|
|
|
|
|
// has bytes. The output is an increasing series, starting at 1 for the first
|
|
|
|
|
// sample, and then increasing by 1 for each sample.
|
|
|
|
|
class CountingSamplesDecoder : public AudioDecoder {
|
|
|
|
|
public:
|
2014-11-04 11:51:46 +00:00
|
|
|
CountingSamplesDecoder() : next_value_(1) {}
|
2014-04-07 21:21:45 +00:00
|
|
|
|
|
|
|
|
// Produce as many samples as input bytes (|encoded_len|).
|
2015-12-08 13:41:35 +01:00
|
|
|
int DecodeInternal(const uint8_t* encoded,
|
|
|
|
|
size_t encoded_len,
|
|
|
|
|
int /* sample_rate_hz */,
|
|
|
|
|
int16_t* decoded,
|
|
|
|
|
SpeechType* speech_type) override {
|
2014-04-07 21:21:45 +00:00
|
|
|
for (size_t i = 0; i < encoded_len; ++i) {
|
|
|
|
|
decoded[i] = next_value_++;
|
|
|
|
|
}
|
|
|
|
|
*speech_type = kSpeech;
|
|
|
|
|
return encoded_len;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-27 15:22:11 +02:00
|
|
|
void Reset() override { next_value_ = 1; }
|
2014-04-07 21:21:45 +00:00
|
|
|
|
2015-03-18 09:47:08 +00:00
|
|
|
size_t Channels() const override { return 1; }
|
|
|
|
|
|
2014-04-07 21:21:45 +00:00
|
|
|
uint16_t next_value() const { return next_value_; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
int16_t next_value_;
|
2014-11-04 11:51:46 +00:00
|
|
|
} decoder_;
|
2014-04-07 21:21:45 +00:00
|
|
|
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
|
|
|
|
&decoder_, NetEqDecoder::kDecoderPCM16B,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateHz));
|
2014-04-07 21:21:45 +00:00
|
|
|
|
|
|
|
|
// Insert one packet.
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-04-07 21:21:45 +00:00
|
|
|
|
|
|
|
|
// Pull audio once.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
|
2014-04-07 21:21:45 +00:00
|
|
|
|
|
|
|
|
// Start with a simple check that the fake decoder is behaving as expected.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
EXPECT_EQ(kPayloadLengthSamples,
|
|
|
|
|
static_cast<size_t>(decoder_.next_value() - 1));
|
2014-04-07 21:21:45 +00:00
|
|
|
|
|
|
|
|
// The value of the last of the output samples is the same as the number of
|
|
|
|
|
// samples played from the decoded packet. Thus, this number + the RTP
|
|
|
|
|
// timestamp should match the playout timestamp.
|
2016-04-06 01:39:22 -07:00
|
|
|
// Wrap the expected value in an rtc::Optional to compare them as such.
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
rtc::Optional<uint32_t>(rtp_header.header.timestamp +
|
|
|
|
|
output.data_[output.samples_per_channel_ - 1]),
|
|
|
|
|
neteq_->GetPlayoutTimestamp());
|
2014-04-07 21:21:45 +00:00
|
|
|
|
|
|
|
|
// Check the timestamp for the last value in the sync buffer. This should
|
|
|
|
|
// be one full frame length ahead of the RTP timestamp.
|
|
|
|
|
const SyncBuffer* sync_buffer = neteq_->sync_buffer_for_test();
|
|
|
|
|
ASSERT_TRUE(sync_buffer != NULL);
|
|
|
|
|
EXPECT_EQ(rtp_header.header.timestamp + kPayloadLengthSamples,
|
|
|
|
|
sync_buffer->end_timestamp());
|
|
|
|
|
|
|
|
|
|
// Check that the number of samples still to play from the sync buffer add
|
|
|
|
|
// up with what was already played out.
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
kPayloadLengthSamples - output.data_[output.samples_per_channel_ - 1],
|
|
|
|
|
sync_buffer->FutureLength());
|
2014-04-07 21:21:45 +00:00
|
|
|
}
|
|
|
|
|
|
2014-11-04 14:03:58 +00:00
|
|
|
TEST_F(NetEqImplTest, ReorderedPacket) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kPayloadLengthSamples =
|
|
|
|
|
static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
|
2014-11-04 14:03:58 +00:00
|
|
|
const size_t kPayloadLengthBytes = kPayloadLengthSamples;
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// Create a mock decoder object.
|
|
|
|
|
MockAudioDecoder mock_decoder;
|
2015-08-27 15:22:11 +02:00
|
|
|
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
|
2015-03-18 09:47:08 +00:00
|
|
|
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
|
2014-11-04 14:03:58 +00:00
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
|
|
|
|
|
.WillRepeatedly(Return(0));
|
2016-04-26 06:19:18 -07:00
|
|
|
EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
|
|
|
|
|
.WillRepeatedly(Return(kPayloadLengthSamples));
|
2014-11-04 14:03:58 +00:00
|
|
|
int16_t dummy_output[kPayloadLengthSamples] = {0};
|
|
|
|
|
// The below expectation will make the mock decoder write
|
|
|
|
|
// |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
|
|
|
|
|
kSampleRateHz, _, _))
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2014-11-04 14:03:58 +00:00
|
|
|
dummy_output + kPayloadLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2014-11-04 14:03:58 +00:00
|
|
|
Return(kPayloadLengthSamples)));
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
|
|
|
|
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateHz));
|
2014-11-04 14:03:58 +00:00
|
|
|
|
|
|
|
|
// Insert one packet.
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-11-04 14:03:58 +00:00
|
|
|
|
|
|
|
|
// Pull audio once.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
|
2014-11-04 14:03:58 +00:00
|
|
|
|
|
|
|
|
// Insert two more packets. The first one is out of order, and is already too
|
|
|
|
|
// old, the second one is the expected next packet.
|
|
|
|
|
rtp_header.header.sequenceNumber -= 1;
|
|
|
|
|
rtp_header.header.timestamp -= kPayloadLengthSamples;
|
|
|
|
|
payload[0] = 1;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-11-04 14:03:58 +00:00
|
|
|
rtp_header.header.sequenceNumber += 2;
|
|
|
|
|
rtp_header.header.timestamp += 2 * kPayloadLengthSamples;
|
|
|
|
|
payload[0] = 2;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-11-04 14:03:58 +00:00
|
|
|
|
|
|
|
|
// Expect only the second packet to be decoded (the one with "2" as the first
|
|
|
|
|
// payload byte).
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
|
|
|
|
|
kSampleRateHz, _, _))
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2014-11-04 14:03:58 +00:00
|
|
|
dummy_output + kPayloadLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2014-11-04 14:03:58 +00:00
|
|
|
Return(kPayloadLengthSamples)));
|
|
|
|
|
|
|
|
|
|
// Pull audio once.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
|
2014-11-04 14:03:58 +00:00
|
|
|
|
|
|
|
|
// Now check the packet buffer, and make sure it is empty, since the
|
|
|
|
|
// out-of-order packet should have been discarded.
|
|
|
|
|
EXPECT_TRUE(packet_buffer_->Empty());
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(mock_decoder, Die());
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-20 11:01:02 +00:00
|
|
|
// This test verifies that NetEq can handle the situation where the first
|
|
|
|
|
// incoming packet is rejected.
|
2014-11-20 14:14:49 +00:00
|
|
|
TEST_F(NetEqImplTest, FirstPacketUnknown) {
|
2014-11-20 11:01:02 +00:00
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kPayloadLengthSamples =
|
|
|
|
|
static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
|
2014-11-20 11:01:02 +00:00
|
|
|
const size_t kPayloadLengthBytes = kPayloadLengthSamples;
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// Insert one packet. Note that we have not registered any payload type, so
|
|
|
|
|
// this packet will be rejected.
|
|
|
|
|
EXPECT_EQ(NetEq::kFail,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-11-20 11:01:02 +00:00
|
|
|
EXPECT_EQ(NetEq::kUnknownRtpPayloadType, neteq_->LastError());
|
|
|
|
|
|
|
|
|
|
// Pull audio once.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
|
|
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
|
2014-11-20 11:01:02 +00:00
|
|
|
|
|
|
|
|
// Register the payload type.
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterPayloadType(
|
2015-12-09 06:20:58 -08:00
|
|
|
NetEqDecoder::kDecoderPCM16B, "", kPayloadType));
|
2014-11-20 11:01:02 +00:00
|
|
|
|
|
|
|
|
// Insert 10 packets.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
for (size_t i = 0; i < 10; ++i) {
|
2014-11-20 11:01:02 +00:00
|
|
|
rtp_header.header.sequenceNumber++;
|
|
|
|
|
rtp_header.header.timestamp += kPayloadLengthSamples;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-11-20 11:01:02 +00:00
|
|
|
EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pull audio repeatedly and make sure we get normal output, that is not PLC.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
for (size_t i = 0; i < 3; ++i) {
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_LE(output.samples_per_channel_, kMaxOutputSize);
|
|
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_)
|
2014-11-20 11:01:02 +00:00
|
|
|
<< "NetEq did not decode the packets as expected.";
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-09 10:46:39 +00:00
|
|
|
|
|
|
|
|
// This test verifies that NetEq can handle comfort noise and enters/quits codec
|
|
|
|
|
// internal CNG mode properly.
|
|
|
|
|
TEST_F(NetEqImplTest, CodecInternalCng) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateKhz = 48;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kPayloadLengthSamples =
|
|
|
|
|
static_cast<size_t>(20 * kSampleRateKhz); // 20 ms.
|
|
|
|
|
const size_t kPayloadLengthBytes = 10;
|
2014-12-09 10:46:39 +00:00
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
int16_t dummy_output[kPayloadLengthSamples] = {0};
|
|
|
|
|
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// Create a mock decoder object.
|
|
|
|
|
MockAudioDecoder mock_decoder;
|
2015-08-27 15:22:11 +02:00
|
|
|
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
|
2015-03-18 09:47:08 +00:00
|
|
|
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
|
2014-12-09 10:46:39 +00:00
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
|
|
|
|
|
.WillRepeatedly(Return(0));
|
2016-04-06 12:28:26 -07:00
|
|
|
EXPECT_CALL(mock_decoder, PacketDuration(_, kPayloadLengthBytes))
|
|
|
|
|
.WillRepeatedly(Return(kPayloadLengthSamples));
|
|
|
|
|
// Packed duration when asking the decoder for more CNG data (without a new
|
|
|
|
|
// packet).
|
|
|
|
|
EXPECT_CALL(mock_decoder, PacketDuration(nullptr, 0))
|
|
|
|
|
.WillRepeatedly(Return(kPayloadLengthSamples));
|
2014-12-09 10:46:39 +00:00
|
|
|
|
|
|
|
|
// Pointee(x) verifies that first byte of the payload equals x, this makes it
|
|
|
|
|
// possible to verify that the correct payload is fed to Decode().
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes,
|
|
|
|
|
kSampleRateKhz * 1000, _, _))
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2014-12-09 10:46:39 +00:00
|
|
|
dummy_output + kPayloadLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2014-12-09 10:46:39 +00:00
|
|
|
Return(kPayloadLengthSamples)));
|
|
|
|
|
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes,
|
|
|
|
|
kSampleRateKhz * 1000, _, _))
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2014-12-09 10:46:39 +00:00
|
|
|
dummy_output + kPayloadLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
2014-12-09 10:46:39 +00:00
|
|
|
Return(kPayloadLengthSamples)));
|
|
|
|
|
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder,
|
|
|
|
|
DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _))
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2014-12-09 10:46:39 +00:00
|
|
|
dummy_output + kPayloadLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
2014-12-09 10:46:39 +00:00
|
|
|
Return(kPayloadLengthSamples)));
|
|
|
|
|
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes,
|
|
|
|
|
kSampleRateKhz * 1000, _, _))
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2014-12-09 10:46:39 +00:00
|
|
|
dummy_output + kPayloadLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2014-12-09 10:46:39 +00:00
|
|
|
Return(kPayloadLengthSamples)));
|
|
|
|
|
|
2015-05-25 14:39:56 +02:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
2015-10-29 06:20:28 -07:00
|
|
|
&mock_decoder, NetEqDecoder::kDecoderOpus,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateKhz * 1000));
|
2014-12-09 10:46:39 +00:00
|
|
|
|
|
|
|
|
// Insert one packet (decoder will return speech).
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-12-09 10:46:39 +00:00
|
|
|
|
|
|
|
|
// Insert second packet (decoder will return CNG).
|
|
|
|
|
payload[0] = 1;
|
|
|
|
|
rtp_header.header.sequenceNumber++;
|
|
|
|
|
rtp_header.header.timestamp += kPayloadLengthSamples;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-12-09 10:46:39 +00:00
|
|
|
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
AudioFrame::SpeechType expected_type[8] = {
|
|
|
|
|
AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech,
|
|
|
|
|
AudioFrame::kCNG, AudioFrame::kCNG,
|
|
|
|
|
AudioFrame::kCNG, AudioFrame::kCNG,
|
|
|
|
|
AudioFrame::kNormalSpeech, AudioFrame::kNormalSpeech
|
2014-12-09 10:46:39 +00:00
|
|
|
};
|
|
|
|
|
int expected_timestamp_increment[8] = {
|
|
|
|
|
-1, // will not be used.
|
|
|
|
|
10 * kSampleRateKhz,
|
2016-04-06 12:28:26 -07:00
|
|
|
-1, -1, // timestamp will be empty during CNG mode; indicated by -1 here.
|
|
|
|
|
-1, -1,
|
2014-12-09 10:46:39 +00:00
|
|
|
50 * kSampleRateKhz, 10 * kSampleRateKhz
|
|
|
|
|
};
|
|
|
|
|
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-04-06 01:39:22 -07:00
|
|
|
rtc::Optional<uint32_t> last_timestamp = neteq_->GetPlayoutTimestamp();
|
|
|
|
|
ASSERT_TRUE(last_timestamp);
|
2014-12-09 10:46:39 +00:00
|
|
|
|
2016-04-06 12:28:26 -07:00
|
|
|
// Lambda for verifying the timestamps.
|
|
|
|
|
auto verify_timestamp = [&last_timestamp, &expected_timestamp_increment](
|
|
|
|
|
rtc::Optional<uint32_t> ts, size_t i) {
|
|
|
|
|
if (expected_timestamp_increment[i] == -1) {
|
|
|
|
|
// Expect to get an empty timestamp value during CNG and PLC.
|
|
|
|
|
EXPECT_FALSE(ts) << "i = " << i;
|
|
|
|
|
} else {
|
|
|
|
|
ASSERT_TRUE(ts) << "i = " << i;
|
|
|
|
|
EXPECT_EQ(*ts, *last_timestamp + expected_timestamp_increment[i])
|
|
|
|
|
<< "i = " << i;
|
|
|
|
|
last_timestamp = ts;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
for (size_t i = 1; i < 6; ++i) {
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(expected_type[i - 1], output.speech_type_);
|
|
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-04-06 12:28:26 -07:00
|
|
|
SCOPED_TRACE("");
|
|
|
|
|
verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
|
2014-12-09 10:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Insert third packet, which leaves a gap from last packet.
|
|
|
|
|
payload[0] = 2;
|
|
|
|
|
rtp_header.header.sequenceNumber += 2;
|
|
|
|
|
rtp_header.header.timestamp += 2 * kPayloadLengthSamples;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2014-12-09 10:46:39 +00:00
|
|
|
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
for (size_t i = 6; i < 8; ++i) {
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(expected_type[i - 1], output.speech_type_);
|
|
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-04-06 12:28:26 -07:00
|
|
|
SCOPED_TRACE("");
|
|
|
|
|
verify_timestamp(neteq_->GetPlayoutTimestamp(), i);
|
2014-12-09 10:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Now check the packet buffer, and make sure it is empty.
|
|
|
|
|
EXPECT_TRUE(packet_buffer_->Empty());
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(mock_decoder, Die());
|
|
|
|
|
}
|
2015-03-16 12:30:37 +00:00
|
|
|
|
|
|
|
|
TEST_F(NetEqImplTest, UnsupportedDecoder) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
static const size_t kNetEqMaxFrameSize = 2880; // 60 ms @ 48 kHz.
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
static const size_t kChannels = 2;
|
2015-03-16 12:30:37 +00:00
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
|
|
|
|
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t kPayloadLengthSamples =
|
|
|
|
|
static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
|
2015-03-16 12:30:37 +00:00
|
|
|
const size_t kPayloadLengthBytes = 1;
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes]= {0};
|
2015-05-25 13:49:37 +02:00
|
|
|
int16_t dummy_output[kPayloadLengthSamples * kChannels] = {0};
|
2015-03-16 12:30:37 +00:00
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
class MockAudioDecoder : public AudioDecoder {
|
|
|
|
|
public:
|
2015-08-27 15:22:11 +02:00
|
|
|
void Reset() override {}
|
2015-03-16 12:30:37 +00:00
|
|
|
MOCK_CONST_METHOD2(PacketDuration, int(const uint8_t*, size_t));
|
|
|
|
|
MOCK_METHOD5(DecodeInternal, int(const uint8_t*, size_t, int, int16_t*,
|
|
|
|
|
SpeechType*));
|
2015-05-25 13:49:37 +02:00
|
|
|
size_t Channels() const override { return kChannels; }
|
2015-03-16 12:30:37 +00:00
|
|
|
} decoder_;
|
|
|
|
|
|
|
|
|
|
const uint8_t kFirstPayloadValue = 1;
|
|
|
|
|
const uint8_t kSecondPayloadValue = 2;
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(decoder_, PacketDuration(Pointee(kFirstPayloadValue),
|
|
|
|
|
kPayloadLengthBytes))
|
|
|
|
|
.Times(AtLeast(1))
|
2015-05-25 13:49:37 +02:00
|
|
|
.WillRepeatedly(Return(kNetEqMaxFrameSize + 1));
|
2015-03-16 12:30:37 +00:00
|
|
|
|
|
|
|
|
EXPECT_CALL(decoder_,
|
|
|
|
|
DecodeInternal(Pointee(kFirstPayloadValue), _, _, _, _))
|
|
|
|
|
.Times(0);
|
|
|
|
|
|
|
|
|
|
EXPECT_CALL(decoder_, DecodeInternal(Pointee(kSecondPayloadValue),
|
|
|
|
|
kPayloadLengthBytes,
|
|
|
|
|
kSampleRateHz, _, _))
|
|
|
|
|
.Times(1)
|
|
|
|
|
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
|
2015-05-25 13:49:37 +02:00
|
|
|
dummy_output +
|
|
|
|
|
kPayloadLengthSamples * kChannels),
|
2015-03-16 12:30:37 +00:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
Return(static_cast<int>(
|
|
|
|
|
kPayloadLengthSamples * kChannels))));
|
2015-03-16 12:30:37 +00:00
|
|
|
|
|
|
|
|
EXPECT_CALL(decoder_, PacketDuration(Pointee(kSecondPayloadValue),
|
|
|
|
|
kPayloadLengthBytes))
|
|
|
|
|
.Times(AtLeast(1))
|
2015-05-25 13:49:37 +02:00
|
|
|
.WillRepeatedly(Return(kNetEqMaxFrameSize));
|
2015-03-16 12:30:37 +00:00
|
|
|
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
|
|
|
|
&decoder_, NetEqDecoder::kDecoderPCM16B,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateHz));
|
2015-03-16 12:30:37 +00:00
|
|
|
|
|
|
|
|
// Insert one packet.
|
|
|
|
|
payload[0] = kFirstPayloadValue; // This will make Decode() fail.
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2015-03-16 12:30:37 +00:00
|
|
|
|
|
|
|
|
// Insert another packet.
|
|
|
|
|
payload[0] = kSecondPayloadValue; // This will make Decode() successful.
|
|
|
|
|
rtp_header.header.sequenceNumber++;
|
|
|
|
|
// The second timestamp needs to be at least 30 ms after the first to make
|
|
|
|
|
// the second packet get decoded.
|
|
|
|
|
rtp_header.header.timestamp += 3 * kPayloadLengthSamples;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2015-03-16 12:30:37 +00:00
|
|
|
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
|
|
|
|
// First call to GetAudio will try to decode the "faulty" packet.
|
|
|
|
|
// Expect kFail return value...
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
// ... and kOtherDecoderError error code.
|
2015-03-16 12:30:37 +00:00
|
|
|
EXPECT_EQ(NetEq::kOtherDecoderError, neteq_->LastError());
|
2016-03-04 10:34:21 -08:00
|
|
|
// 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_);
|
|
|
|
|
|
|
|
|
|
// Second call to GetAudio will decode the packet that is ok. No errors are
|
|
|
|
|
// expected.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kExpectedOutputSize, output.samples_per_channel_ * kChannels);
|
|
|
|
|
EXPECT_EQ(kChannels, output.num_channels_);
|
2015-03-16 12:30:37 +00:00
|
|
|
}
|
|
|
|
|
|
NetEq: Fixing a bug that caused rtc::checked_cast to trigger
This is a bug that was introduced in
https://codereview.webrtc.org/1230503003, where the variable "int
temp_bufsize" was changed to a size_t. If the packet buffer was
flushed while inserting a packet, temp_bufsize became negative, which
was tested later in an if-statement. Now, with size_t instead, it
would just become very large, and the if-statement would never see a
negative value. The effect was that the packet size in samples could
be updated with a very large positive number, causing an overflow
which triggered rtc::checked_cast in
StatisticsCalculator::GetNetworkStatistics, line 220.
Also adding a test to reproduce the crash. Without the fix, the test
results in the above mentioned checked_cast to trigger. With the fix,
everything works fine.
BUG=chromium:525260
Review URL: https://codereview.webrtc.org/1307893004
Cr-Commit-Position: refs/heads/master@{#9802}
2015-08-27 13:14:48 -07:00
|
|
|
// This test inserts packets until the buffer is flushed. After that, it asks
|
|
|
|
|
// NetEq for the network statistics. The purpose of the test is to make sure
|
|
|
|
|
// that even though the buffer size increment is negative (which it becomes when
|
|
|
|
|
// the packet causing a flush is inserted), the packet length stored in the
|
|
|
|
|
// decision logic remains valid.
|
|
|
|
|
TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const size_t kPayloadLengthSamples = 80;
|
|
|
|
|
const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit.
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterPayloadType(
|
2015-12-09 06:20:58 -08:00
|
|
|
NetEqDecoder::kDecoderPCM16B, "", kPayloadType));
|
NetEq: Fixing a bug that caused rtc::checked_cast to trigger
This is a bug that was introduced in
https://codereview.webrtc.org/1230503003, where the variable "int
temp_bufsize" was changed to a size_t. If the packet buffer was
flushed while inserting a packet, temp_bufsize became negative, which
was tested later in an if-statement. Now, with size_t instead, it
would just become very large, and the if-statement would never see a
negative value. The effect was that the packet size in samples could
be updated with a very large positive number, causing an overflow
which triggered rtc::checked_cast in
StatisticsCalculator::GetNetworkStatistics, line 220.
Also adding a test to reproduce the crash. Without the fix, the test
results in the above mentioned checked_cast to trigger. With the fix,
everything works fine.
BUG=chromium:525260
Review URL: https://codereview.webrtc.org/1307893004
Cr-Commit-Position: refs/heads/master@{#9802}
2015-08-27 13:14:48 -07:00
|
|
|
|
|
|
|
|
// Insert packets until the buffer flushes.
|
|
|
|
|
for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
|
|
|
|
|
EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
NetEq: Fixing a bug that caused rtc::checked_cast to trigger
This is a bug that was introduced in
https://codereview.webrtc.org/1230503003, where the variable "int
temp_bufsize" was changed to a size_t. If the packet buffer was
flushed while inserting a packet, temp_bufsize became negative, which
was tested later in an if-statement. Now, with size_t instead, it
would just become very large, and the if-statement would never see a
negative value. The effect was that the packet size in samples could
be updated with a very large positive number, causing an overflow
which triggered rtc::checked_cast in
StatisticsCalculator::GetNetworkStatistics, line 220.
Also adding a test to reproduce the crash. Without the fix, the test
results in the above mentioned checked_cast to trigger. With the fix,
everything works fine.
BUG=chromium:525260
Review URL: https://codereview.webrtc.org/1307893004
Cr-Commit-Position: refs/heads/master@{#9802}
2015-08-27 13:14:48 -07:00
|
|
|
rtp_header.header.timestamp +=
|
|
|
|
|
rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
|
|
|
|
|
++rtp_header.header.sequenceNumber;
|
|
|
|
|
}
|
|
|
|
|
EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
|
|
|
|
|
|
|
|
|
|
// Ask for network statistics. This should not crash.
|
|
|
|
|
NetEqNetworkStatistics stats;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->NetworkStatistics(&stats));
|
|
|
|
|
}
|
2015-09-01 11:51:58 +02:00
|
|
|
|
|
|
|
|
TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
|
|
|
|
const size_t kPayloadLengthSamples =
|
|
|
|
|
static_cast<size_t>(10 * kSampleRateHz / 1000); // 10 ms.
|
|
|
|
|
const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples;
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// Create a mock decoder object.
|
|
|
|
|
MockAudioDecoder mock_decoder;
|
|
|
|
|
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
|
|
|
|
|
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
|
|
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
|
|
|
|
|
.WillRepeatedly(Return(0));
|
|
|
|
|
EXPECT_CALL(mock_decoder, PacketDuration(_, _))
|
|
|
|
|
.WillRepeatedly(Return(kPayloadLengthSamples));
|
|
|
|
|
int16_t dummy_output[kPayloadLengthSamples] = {0};
|
|
|
|
|
// The below expectation will make the mock decoder write
|
|
|
|
|
// |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as
|
|
|
|
|
// speech. That is, the decoded length is 5 samples shorter than the expected.
|
|
|
|
|
EXPECT_CALL(mock_decoder,
|
2015-12-08 13:41:35 +01:00
|
|
|
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
|
2015-09-01 11:51:58 +02:00
|
|
|
.WillOnce(
|
2015-12-08 13:41:35 +01:00
|
|
|
DoAll(SetArrayArgument<3>(dummy_output,
|
2015-09-01 11:51:58 +02:00
|
|
|
dummy_output + kPayloadLengthSamples - 5),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2015-09-01 11:51:58 +02:00
|
|
|
Return(kPayloadLengthSamples - 5)));
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
|
|
|
|
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateHz));
|
2015-09-01 11:51:58 +02:00
|
|
|
|
|
|
|
|
// Insert one packet.
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2015-09-01 11:51:58 +02:00
|
|
|
|
|
|
|
|
EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
|
|
|
|
|
|
|
|
|
|
// Pull audio once.
|
|
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
ASSERT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
|
2015-09-01 11:51:58 +02:00
|
|
|
|
|
|
|
|
EXPECT_CALL(mock_decoder, Die());
|
|
|
|
|
}
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// This test checks the behavior of NetEq when audio decoder fails.
|
|
|
|
|
TEST_F(NetEqImplTest, DecodingError) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
|
|
|
|
const int kDecoderErrorCode = -97; // Any negative number.
|
|
|
|
|
|
|
|
|
|
// We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
|
|
|
|
|
const size_t kFrameLengthSamples =
|
|
|
|
|
static_cast<size_t>(5 * kSampleRateHz / 1000);
|
|
|
|
|
|
|
|
|
|
const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
|
|
|
|
|
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// Create a mock decoder object.
|
|
|
|
|
MockAudioDecoder mock_decoder;
|
|
|
|
|
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
|
|
|
|
|
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
|
|
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
|
|
|
|
|
.WillRepeatedly(Return(0));
|
|
|
|
|
EXPECT_CALL(mock_decoder, PacketDuration(_, _))
|
|
|
|
|
.WillRepeatedly(Return(kFrameLengthSamples));
|
|
|
|
|
EXPECT_CALL(mock_decoder, ErrorCode())
|
|
|
|
|
.WillOnce(Return(kDecoderErrorCode));
|
|
|
|
|
EXPECT_CALL(mock_decoder, HasDecodePlc())
|
|
|
|
|
.WillOnce(Return(false));
|
|
|
|
|
int16_t dummy_output[kFrameLengthSamples] = {0};
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
InSequence sequence; // Dummy variable.
|
|
|
|
|
// Mock decoder works normally the first time.
|
|
|
|
|
EXPECT_CALL(mock_decoder,
|
2015-12-08 13:41:35 +01:00
|
|
|
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
|
2015-09-23 15:20:39 +02:00
|
|
|
.Times(3)
|
|
|
|
|
.WillRepeatedly(
|
2015-12-08 13:41:35 +01:00
|
|
|
DoAll(SetArrayArgument<3>(dummy_output,
|
2015-09-23 15:20:39 +02:00
|
|
|
dummy_output + kFrameLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2015-09-23 15:20:39 +02:00
|
|
|
Return(kFrameLengthSamples)))
|
|
|
|
|
.RetiresOnSaturation();
|
|
|
|
|
|
|
|
|
|
// Then mock decoder fails. A common reason for failure can be buffer being
|
|
|
|
|
// too short
|
|
|
|
|
EXPECT_CALL(mock_decoder,
|
2015-12-08 13:41:35 +01:00
|
|
|
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
|
2015-09-23 15:20:39 +02:00
|
|
|
.WillOnce(Return(-1))
|
|
|
|
|
.RetiresOnSaturation();
|
|
|
|
|
|
|
|
|
|
// Mock decoder finally returns to normal.
|
|
|
|
|
EXPECT_CALL(mock_decoder,
|
2015-12-08 13:41:35 +01:00
|
|
|
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
|
2015-09-23 15:20:39 +02:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(
|
2015-12-08 13:41:35 +01:00
|
|
|
DoAll(SetArrayArgument<3>(dummy_output,
|
|
|
|
|
dummy_output + kFrameLengthSamples),
|
|
|
|
|
SetArgPointee<4>(AudioDecoder::kSpeech),
|
2015-09-23 15:20:39 +02:00
|
|
|
Return(kFrameLengthSamples)));
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
|
|
|
|
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateHz));
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Insert packets.
|
|
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
|
|
|
rtp_header.header.sequenceNumber += 1;
|
|
|
|
|
rtp_header.header.timestamp += kFrameLengthSamples;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2015-09-23 15:20:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pull audio.
|
|
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Pull audio again. Decoder fails.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output));
|
2015-09-23 15:20:39 +02:00
|
|
|
EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
|
|
|
|
|
EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError());
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
// We are not expecting anything for output.speech_type_, since an error was
|
|
|
|
|
// returned.
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Pull audio again, should continue an expansion.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kPLC, output.speech_type_);
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Pull audio again, should behave normal.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kNormalSpeech, output.speech_type_);
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
EXPECT_CALL(mock_decoder, Die());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This test checks the behavior of NetEq when audio decoder fails during CNG.
|
|
|
|
|
TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
|
|
|
|
|
const uint8_t kPayloadType = 17; // Just an arbitrary number.
|
|
|
|
|
const uint32_t kReceiveTime = 17; // Value doesn't matter for this test.
|
|
|
|
|
const int kSampleRateHz = 8000;
|
|
|
|
|
const int kDecoderErrorCode = -97; // Any negative number.
|
|
|
|
|
|
|
|
|
|
// We let decoder return 5 ms each time, and therefore, 2 packets make 10 ms.
|
|
|
|
|
const size_t kFrameLengthSamples =
|
|
|
|
|
static_cast<size_t>(5 * kSampleRateHz / 1000);
|
|
|
|
|
|
|
|
|
|
const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
|
|
|
|
|
|
|
|
|
|
uint8_t payload[kPayloadLengthBytes] = {0};
|
|
|
|
|
|
|
|
|
|
WebRtcRTPHeader rtp_header;
|
|
|
|
|
rtp_header.header.payloadType = kPayloadType;
|
|
|
|
|
rtp_header.header.sequenceNumber = 0x1234;
|
|
|
|
|
rtp_header.header.timestamp = 0x12345678;
|
|
|
|
|
rtp_header.header.ssrc = 0x87654321;
|
|
|
|
|
|
|
|
|
|
// Create a mock decoder object.
|
|
|
|
|
MockAudioDecoder mock_decoder;
|
|
|
|
|
EXPECT_CALL(mock_decoder, Reset()).WillRepeatedly(Return());
|
|
|
|
|
EXPECT_CALL(mock_decoder, Channels()).WillRepeatedly(Return(1));
|
|
|
|
|
EXPECT_CALL(mock_decoder, IncomingPacket(_, kPayloadLengthBytes, _, _, _))
|
|
|
|
|
.WillRepeatedly(Return(0));
|
|
|
|
|
EXPECT_CALL(mock_decoder, PacketDuration(_, _))
|
|
|
|
|
.WillRepeatedly(Return(kFrameLengthSamples));
|
|
|
|
|
EXPECT_CALL(mock_decoder, ErrorCode())
|
|
|
|
|
.WillOnce(Return(kDecoderErrorCode));
|
|
|
|
|
int16_t dummy_output[kFrameLengthSamples] = {0};
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
InSequence sequence; // Dummy variable.
|
|
|
|
|
// Mock decoder works normally the first 2 times.
|
|
|
|
|
EXPECT_CALL(mock_decoder,
|
2015-12-08 13:41:35 +01:00
|
|
|
DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _))
|
2015-09-23 15:20:39 +02:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(
|
2015-12-08 13:41:35 +01:00
|
|
|
DoAll(SetArrayArgument<3>(dummy_output,
|
2015-09-23 15:20:39 +02:00
|
|
|
dummy_output + kFrameLengthSamples),
|
2015-12-08 13:41:35 +01:00
|
|
|
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
2015-09-23 15:20:39 +02:00
|
|
|
Return(kFrameLengthSamples)))
|
|
|
|
|
.RetiresOnSaturation();
|
|
|
|
|
|
|
|
|
|
// Then mock decoder fails. A common reason for failure can be buffer being
|
|
|
|
|
// too short
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
|
2015-09-23 15:20:39 +02:00
|
|
|
.WillOnce(Return(-1))
|
|
|
|
|
.RetiresOnSaturation();
|
|
|
|
|
|
|
|
|
|
// Mock decoder finally returns to normal.
|
2015-12-08 13:41:35 +01:00
|
|
|
EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _))
|
2015-09-23 15:20:39 +02:00
|
|
|
.Times(2)
|
|
|
|
|
.WillRepeatedly(
|
2015-12-08 13:41:35 +01:00
|
|
|
DoAll(SetArrayArgument<3>(dummy_output,
|
|
|
|
|
dummy_output + kFrameLengthSamples),
|
|
|
|
|
SetArgPointee<4>(AudioDecoder::kComfortNoise),
|
2015-09-23 15:20:39 +02:00
|
|
|
Return(kFrameLengthSamples)));
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-29 06:20:28 -07:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder(
|
|
|
|
|
&mock_decoder, NetEqDecoder::kDecoderPCM16B,
|
2015-12-09 06:20:58 -08:00
|
|
|
"dummy name", kPayloadType, kSampleRateHz));
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Insert 2 packets. This will make netEq into codec internal CNG mode.
|
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
|
rtp_header.header.sequenceNumber += 1;
|
|
|
|
|
rtp_header.header.timestamp += kFrameLengthSamples;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK,
|
2015-11-11 10:34:00 -08:00
|
|
|
neteq_->InsertPacket(rtp_header, payload, kReceiveTime));
|
2015-09-23 15:20:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pull audio.
|
|
|
|
|
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
|
2016-03-04 10:34:21 -08:00
|
|
|
AudioFrame output;
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Pull audio again. Decoder fails.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(&output));
|
2015-09-23 15:20:39 +02:00
|
|
|
EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
|
|
|
|
|
EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError());
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
// We are not expecting anything for output.speech_type_, since an error was
|
|
|
|
|
// returned.
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// Pull audio again, should resume codec CNG.
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
2016-03-04 10:34:21 -08:00
|
|
|
EXPECT_EQ(kMaxOutputSize, output.samples_per_channel_);
|
|
|
|
|
EXPECT_EQ(1u, output.num_channels_);
|
2016-03-08 02:37:57 -08:00
|
|
|
EXPECT_EQ(AudioFrame::kCNG, output.speech_type_);
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
EXPECT_CALL(mock_decoder, Die());
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-23 06:49:25 -08:00
|
|
|
// Tests that the return value from last_output_sample_rate_hz() is equal to the
|
|
|
|
|
// configured inital sample rate.
|
|
|
|
|
TEST_F(NetEqImplTest, InitialLastOutputSampleRate) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
config_.sample_rate_hz = 48000;
|
|
|
|
|
CreateInstance();
|
|
|
|
|
EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz());
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-25 10:11:38 -07:00
|
|
|
TEST_F(NetEqImplTest, TickTimerIncrement) {
|
|
|
|
|
UseNoMocks();
|
|
|
|
|
CreateInstance();
|
|
|
|
|
ASSERT_TRUE(tick_timer_);
|
|
|
|
|
EXPECT_EQ(0u, tick_timer_->ticks());
|
|
|
|
|
AudioFrame output;
|
|
|
|
|
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output));
|
|
|
|
|
EXPECT_EQ(1u, tick_timer_->ticks());
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 15:20:39 +02:00
|
|
|
}// namespace webrtc
|