Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 const size_t kOpusRateKhz = 48; | 31 const size_t kOpusRateKhz = 48; |
| 32 // Number of samples-per-channel in a 20 ms frame, sampled at 48 kHz. | 32 // Number of samples-per-channel in a 20 ms frame, sampled at 48 kHz. |
| 33 const size_t kOpus20msFrameSamples = kOpusRateKhz * 20; | 33 const size_t kOpus20msFrameSamples = kOpusRateKhz * 20; |
| 34 // Number of samples-per-channel in a 10 ms frame, sampled at 48 kHz. | 34 // Number of samples-per-channel in a 10 ms frame, sampled at 48 kHz. |
| 35 const size_t kOpus10msFrameSamples = kOpusRateKhz * 10; | 35 const size_t kOpus10msFrameSamples = kOpusRateKhz * 10; |
| 36 | 36 |
| 37 class OpusTest : public TestWithParam<::testing::tuple<int, int>> { | 37 class OpusTest : public TestWithParam<::testing::tuple<int, int>> { |
| 38 protected: | 38 protected: |
| 39 OpusTest(); | 39 OpusTest(); |
| 40 | 40 |
| 41 void TestDtxEffect(bool dtx, int block_length_ms); | 41 void TestDtxAndCbrEffect(bool dtx, bool cbr, int block_length_ms); |
|
minyue-webrtc
2017/03/31 18:37:43
Merging DTX and CBR into this function isn't good.
| |
| 42 | 42 |
| 43 // Prepare |speech_data_| for encoding, read from a hard-coded file. | 43 // Prepare |speech_data_| for encoding, read from a hard-coded file. |
| 44 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a | 44 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a |
| 45 // block of |block_length_ms| milliseconds. The data is looped every | 45 // block of |block_length_ms| milliseconds. The data is looped every |
| 46 // |loop_length_ms| milliseconds. | 46 // |loop_length_ms| milliseconds. |
| 47 void PrepareSpeechData(size_t channel, | 47 void PrepareSpeechData(size_t channel, |
| 48 int block_length_ms, | 48 int block_length_ms, |
| 49 int loop_length_ms); | 49 int loop_length_ms); |
| 50 | 50 |
| 51 int EncodeDecode(WebRtcOpusEncInst* encoder, | 51 int EncodeDecode(WebRtcOpusEncInst* encoder, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); | 126 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); |
| 127 int act_len = WebRtcOpus_Decode(decoder, bitstream_, | 127 int act_len = WebRtcOpus_Decode(decoder, bitstream_, |
| 128 encoded_bytes_, output_audio, | 128 encoded_bytes_, output_audio, |
| 129 audio_type); | 129 audio_type); |
| 130 EXPECT_EQ(est_len, act_len); | 130 EXPECT_EQ(est_len, act_len); |
| 131 return act_len; | 131 return act_len; |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Test if encoder/decoder can enter DTX mode properly and do not enter DTX when | 134 // Test if encoder/decoder can enter DTX mode properly and do not enter DTX when |
| 135 // they should not. This test is signal dependent. | 135 // they should not. This test is signal dependent. |
| 136 void OpusTest::TestDtxEffect(bool dtx, int block_length_ms) { | 136 void OpusTest::TestDtxAndCbrEffect(bool dtx, bool cbr, int block_length_ms) { |
| 137 PrepareSpeechData(channels_, block_length_ms, 2000); | 137 PrepareSpeechData(channels_, block_length_ms, 2000); |
| 138 const size_t samples = kOpusRateKhz * block_length_ms; | 138 const size_t samples = kOpusRateKhz * block_length_ms; |
| 139 int32_t max_pkt_size_diff = 0; | |
| 140 int32_t prev_pkt_size = 0; | |
| 139 | 141 |
| 140 // Create encoder memory. | 142 // Create encoder memory. |
| 141 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, | 143 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, |
| 142 channels_, | 144 channels_, |
| 143 application_)); | 145 application_)); |
| 144 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); | 146 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); |
| 145 | 147 |
| 146 // Set bitrate. | 148 // Set bitrate. |
| 147 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, | 149 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, |
| 148 channels_ == 1 ? 32000 : 64000)); | 150 channels_ == 1 ? 32000 : 64000)); |
| 149 | 151 |
| 150 // Set input audio as silence. | 152 // Set input audio as silence. |
| 151 std::vector<int16_t> silence(samples * channels_, 0); | 153 std::vector<int16_t> silence(samples * channels_, 0); |
| 152 | 154 |
| 153 // Setting DTX. | 155 // Setting DTX. |
| 154 EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) : | 156 EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) : |
| 155 WebRtcOpus_DisableDtx(opus_encoder_)); | 157 WebRtcOpus_DisableDtx(opus_encoder_)); |
| 156 | 158 |
| 159 // Setting CBR. | |
| 160 EXPECT_EQ(0, cbr ? WebRtcOpus_EnableCbr(opus_encoder_) | |
| 161 : WebRtcOpus_DisableCbr(opus_encoder_)); | |
| 162 | |
| 157 int16_t audio_type; | 163 int16_t audio_type; |
| 158 int16_t* output_data_decode = new int16_t[samples * channels_]; | 164 int16_t* output_data_decode = new int16_t[samples * channels_]; |
| 159 | 165 |
| 160 for (int i = 0; i < 100; ++i) { | 166 for (int i = 0; i < 100; ++i) { |
| 161 EXPECT_EQ(samples, | 167 EXPECT_EQ(samples, |
| 162 static_cast<size_t>(EncodeDecode( | 168 static_cast<size_t>(EncodeDecode( |
| 163 opus_encoder_, speech_data_.GetNextBlock(), opus_decoder_, | 169 opus_encoder_, speech_data_.GetNextBlock(), opus_decoder_, |
| 164 output_data_decode, &audio_type))); | 170 output_data_decode, &audio_type))); |
| 165 // If not DTX, it should never enter DTX mode. If DTX, we do not care since | 171 // If not DTX, it should never enter DTX mode. If DTX, we do not care since |
| 166 // whether it enters DTX depends on the signal type. | 172 // whether it enters DTX depends on the signal type. |
| 167 if (!dtx) { | 173 if (!dtx) { |
| 168 EXPECT_GT(encoded_bytes_, 1U); | 174 EXPECT_GT(encoded_bytes_, 1U); |
| 169 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 175 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 170 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 176 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 171 EXPECT_EQ(0, audio_type); // Speech. | 177 EXPECT_EQ(0, audio_type); // Speech. |
| 172 } | 178 } |
| 179 if (!opus_encoder_->in_dtx_mode) { | |
| 180 if (prev_pkt_size > 0) { | |
| 181 int32_t diff = std::abs((int32_t)encoded_bytes_ - prev_pkt_size); | |
| 182 max_pkt_size_diff = std::max(max_pkt_size_diff, diff); | |
| 183 } | |
| 184 prev_pkt_size = encoded_bytes_; | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 if (cbr) { | |
| 189 EXPECT_EQ(max_pkt_size_diff, 0); | |
| 190 } else { | |
| 191 EXPECT_GT(max_pkt_size_diff, 0); | |
| 173 } | 192 } |
| 174 | 193 |
| 175 // We input some silent segments. In DTX mode, the encoder will stop sending. | 194 // We input some silent segments. In DTX mode, the encoder will stop sending. |
| 176 // However, DTX may happen after a while. | 195 // However, DTX may happen after a while. |
| 177 for (int i = 0; i < 30; ++i) { | 196 for (int i = 0; i < 30; ++i) { |
| 178 EXPECT_EQ(samples, | 197 EXPECT_EQ(samples, |
| 179 static_cast<size_t>(EncodeDecode( | 198 static_cast<size_t>(EncodeDecode( |
| 180 opus_encoder_, silence, opus_decoder_, output_data_decode, | 199 opus_encoder_, silence, opus_decoder_, output_data_decode, |
| 181 &audio_type))); | 200 &audio_type))); |
| 182 if (!dtx) { | 201 if (!dtx) { |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 opus_encoder_ctl(opus_encoder_->encoder, | 526 opus_encoder_ctl(opus_encoder_->encoder, |
| 508 OPUS_GET_DTX(&dtx)); | 527 OPUS_GET_DTX(&dtx)); |
| 509 EXPECT_EQ(0, dtx); | 528 EXPECT_EQ(0, dtx); |
| 510 | 529 |
| 511 | 530 |
| 512 // Free memory. | 531 // Free memory. |
| 513 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 532 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 514 } | 533 } |
| 515 | 534 |
| 516 TEST_P(OpusTest, OpusDtxOff) { | 535 TEST_P(OpusTest, OpusDtxOff) { |
| 517 TestDtxEffect(false, 10); | 536 TestDtxAndCbrEffect(false, false, 10); |
| 518 TestDtxEffect(false, 20); | 537 TestDtxAndCbrEffect(false, false, 20); |
| 519 TestDtxEffect(false, 40); | 538 TestDtxAndCbrEffect(false, false, 40); |
| 520 } | 539 } |
| 521 | 540 |
| 522 TEST_P(OpusTest, OpusDtxOn) { | 541 TEST_P(OpusTest, OpusDtxOn) { |
| 523 TestDtxEffect(true, 10); | 542 TestDtxAndCbrEffect(true, false, 10); |
| 524 TestDtxEffect(true, 20); | 543 TestDtxAndCbrEffect(true, false, 20); |
| 525 TestDtxEffect(true, 40); | 544 TestDtxAndCbrEffect(true, false, 40); |
| 526 } | 545 } |
| 527 | 546 |
| 547 TEST_P(OpusTest, OpusCbrOn) { | |
| 548 TestDtxAndCbrEffect(false, true, 10); | |
| 549 TestDtxAndCbrEffect(false, true, 20); | |
| 550 TestDtxAndCbrEffect(false, true, 40); | |
| 551 } | |
| 552 | |
| 553 #if 0 // The DTX part fails when both dtx and cbr is on | |
| 554 TEST_P(OpusTest, OpusDtxOnCbrOn) { | |
| 555 TestDtxAndCbrEffect(true, true, 10); | |
| 556 TestDtxAndCbrEffect(true, true, 20); | |
| 557 TestDtxAndCbrEffect(true, true, 40); | |
| 558 } | |
| 559 #endif | |
| 560 | |
| 528 TEST_P(OpusTest, OpusSetPacketLossRate) { | 561 TEST_P(OpusTest, OpusSetPacketLossRate) { |
| 529 // Test without creating encoder memory. | 562 // Test without creating encoder memory. |
| 530 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50)); | 563 EXPECT_EQ(-1, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50)); |
| 531 | 564 |
| 532 // Create encoder memory. | 565 // Create encoder memory. |
| 533 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, | 566 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, |
| 534 channels_, | 567 channels_, |
| 535 application_)); | 568 application_)); |
| 536 | 569 |
| 537 EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50)); | 570 EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_, 50)); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 693 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 726 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 694 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 727 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
| 695 } | 728 } |
| 696 | 729 |
| 697 INSTANTIATE_TEST_CASE_P(VariousMode, | 730 INSTANTIATE_TEST_CASE_P(VariousMode, |
| 698 OpusTest, | 731 OpusTest, |
| 699 Combine(Values(1, 2), Values(0, 1))); | 732 Combine(Values(1, 2), Values(0, 1))); |
| 700 | 733 |
| 701 | 734 |
| 702 } // namespace webrtc | 735 } // namespace webrtc |
| OLD | NEW |