Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Unified Diff: webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc

Issue 1334303005: Returning correct duration estimate on Opus DTX packets. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: fixing a silly mistake in unittest Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/audio_coding/neteq/neteq_impl.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
index 3a3469241c9ca26fd708fd9ffdc8a5302f18ce2d..5489fed91008d5eef1b1c91d40af4a7f745e48eb 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -1005,4 +1005,245 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
EXPECT_CALL(mock_decoder, Die());
}
-} // namespace webrtc
+
+// 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,
+ Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
+ .Times(3)
+ .WillRepeatedly(
+ DoAll(SetArrayArgument<4>(dummy_output,
+ dummy_output + kFrameLengthSamples),
+ SetArgPointee<5>(AudioDecoder::kSpeech),
+ Return(kFrameLengthSamples)))
+ .RetiresOnSaturation();
+
+ // Then mock decoder fails. A common reason for failure can be buffer being
+ // too short
+ EXPECT_CALL(mock_decoder,
+ Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
+ .WillOnce(Return(-1))
+ .RetiresOnSaturation();
+
+ // Mock decoder finally returns to normal.
+ EXPECT_CALL(mock_decoder,
+ Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
+ .Times(2)
+ .WillRepeatedly(
+ DoAll(SetArrayArgument<4>(dummy_output,
+ dummy_output + kFrameLengthSamples),
+ SetArgPointee<5>(AudioDecoder::kSpeech),
+ Return(kFrameLengthSamples)));
+ }
+
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->RegisterExternalDecoder(&mock_decoder, kDecoderPCM16B,
+ kPayloadType, kSampleRateHz));
+
+ // Insert packets.
+ for (int i = 0; i < 6; ++i) {
+ rtp_header.header.sequenceNumber += 1;
+ rtp_header.header.timestamp += kFrameLengthSamples;
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes,
+ kReceiveTime));
+ }
+
+ // Pull audio.
+ const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
+ int16_t output[kMaxOutputSize];
+ size_t samples_per_channel;
+ int num_channels;
+ NetEqOutputType type;
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputNormal, type);
+
+ // Pull audio again. Decoder fails.
+ EXPECT_EQ(NetEq::kFail,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
+ EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError());
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ // TODO(minyue): should NetEq better give kOutputPLC, since it is actually an
+ // expansion.
+ EXPECT_EQ(kOutputNormal, type);
+
+ // Pull audio again, should continue an expansion.
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputPLC, type);
+
+ // Pull audio again, should behave normal.
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputNormal, type);
+
+ 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,
+ Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _))
+ .Times(2)
+ .WillRepeatedly(
+ DoAll(SetArrayArgument<4>(dummy_output,
+ dummy_output + kFrameLengthSamples),
+ SetArgPointee<5>(AudioDecoder::kComfortNoise),
+ Return(kFrameLengthSamples)))
+ .RetiresOnSaturation();
+
+ // Then mock decoder fails. A common reason for failure can be buffer being
+ // too short
+ EXPECT_CALL(mock_decoder, Decode(nullptr, 0, kSampleRateHz, _, _, _))
+ .WillOnce(Return(-1))
+ .RetiresOnSaturation();
+
+ // Mock decoder finally returns to normal.
+ EXPECT_CALL(mock_decoder, Decode(nullptr, 0, kSampleRateHz, _, _, _))
+ .Times(2)
+ .WillRepeatedly(
+ DoAll(SetArrayArgument<4>(dummy_output,
+ dummy_output + kFrameLengthSamples),
+ SetArgPointee<5>(AudioDecoder::kComfortNoise),
+ Return(kFrameLengthSamples)));
+ }
+
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->RegisterExternalDecoder(&mock_decoder, kDecoderPCM16B,
+ kPayloadType, kSampleRateHz));
+
+ // 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,
+ neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes,
+ kReceiveTime));
+ }
+
+ // Pull audio.
+ const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
+ int16_t output[kMaxOutputSize];
+ size_t samples_per_channel;
+ int num_channels;
+ NetEqOutputType type;
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputCNG, type);
+
+ // Pull audio again. Decoder fails.
+ EXPECT_EQ(NetEq::kFail,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError());
+ EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError());
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ // TODO(minyue): should NetEq better give kOutputPLC, since it is actually an
+ // expansion.
+ EXPECT_EQ(kOutputCNG, type);
+
+ // Pull audio again, should resume codec CNG.
+ EXPECT_EQ(NetEq::kOK,
+ neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel,
+ &num_channels, &type));
+ EXPECT_EQ(kMaxOutputSize, samples_per_channel);
+ EXPECT_EQ(1, num_channels);
+ EXPECT_EQ(kOutputCNG, type);
+
+ EXPECT_CALL(mock_decoder, Die());
+}
+
+}// namespace webrtc
« no previous file with comments | « webrtc/modules/audio_coding/neteq/neteq_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698