| 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 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "webrtc/base/checks.h" |
| 13 #include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" | 14 #include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" |
| 14 #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h" | 15 #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h" |
| 15 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" | 16 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" |
| 16 #include "webrtc/test/testsupport/fileutils.h" | 17 #include "webrtc/test/testsupport/fileutils.h" |
| 17 | 18 |
| 18 namespace webrtc { | 19 namespace webrtc { |
| 19 | 20 |
| 20 using test::AudioLoop; | 21 using test::AudioLoop; |
| 21 using ::testing::TestWithParam; | 22 using ::testing::TestWithParam; |
| 22 using ::testing::Values; | 23 using ::testing::Values; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 37 | 38 |
| 38 void TestDtxEffect(bool dtx); | 39 void TestDtxEffect(bool dtx); |
| 39 | 40 |
| 40 // Prepare |speech_data_| for encoding, read from a hard-coded file. | 41 // Prepare |speech_data_| for encoding, read from a hard-coded file. |
| 41 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a | 42 // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a |
| 42 // block of |block_length_ms| milliseconds. The data is looped every | 43 // block of |block_length_ms| milliseconds. The data is looped every |
| 43 // |loop_length_ms| milliseconds. | 44 // |loop_length_ms| milliseconds. |
| 44 void PrepareSpeechData(int channel, int block_length_ms, int loop_length_ms); | 45 void PrepareSpeechData(int channel, int block_length_ms, int loop_length_ms); |
| 45 | 46 |
| 46 int EncodeDecode(WebRtcOpusEncInst* encoder, | 47 int EncodeDecode(WebRtcOpusEncInst* encoder, |
| 47 const int16_t* input_audio, | 48 rtc::ArrayView<const int16_t> input_audio, |
| 48 size_t input_samples, | |
| 49 WebRtcOpusDecInst* decoder, | 49 WebRtcOpusDecInst* decoder, |
| 50 int16_t* output_audio, | 50 int16_t* output_audio, |
| 51 int16_t* audio_type); | 51 int16_t* audio_type); |
| 52 | 52 |
| 53 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, | 53 void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, |
| 54 opus_int32 expect, int32_t set); | 54 opus_int32 expect, int32_t set); |
| 55 | 55 |
| 56 WebRtcOpusEncInst* opus_encoder_; | 56 WebRtcOpusEncInst* opus_encoder_; |
| 57 WebRtcOpusDecInst* opus_decoder_; | 57 WebRtcOpusDecInst* opus_decoder_; |
| 58 | 58 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 89 opus_int32 expect, | 89 opus_int32 expect, |
| 90 int32_t set) { | 90 int32_t set) { |
| 91 opus_int32 bandwidth; | 91 opus_int32 bandwidth; |
| 92 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set)); | 92 EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, set)); |
| 93 opus_encoder_ctl(opus_encoder_->encoder, | 93 opus_encoder_ctl(opus_encoder_->encoder, |
| 94 OPUS_GET_MAX_BANDWIDTH(&bandwidth)); | 94 OPUS_GET_MAX_BANDWIDTH(&bandwidth)); |
| 95 EXPECT_EQ(expect, bandwidth); | 95 EXPECT_EQ(expect, bandwidth); |
| 96 } | 96 } |
| 97 | 97 |
| 98 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, | 98 int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, |
| 99 const int16_t* input_audio, | 99 rtc::ArrayView<const int16_t> input_audio, |
| 100 size_t input_samples, | |
| 101 WebRtcOpusDecInst* decoder, | 100 WebRtcOpusDecInst* decoder, |
| 102 int16_t* output_audio, | 101 int16_t* output_audio, |
| 103 int16_t* audio_type) { | 102 int16_t* audio_type) { |
| 104 int encoded_bytes_int = WebRtcOpus_Encode(encoder, input_audio, input_samples, | 103 int encoded_bytes_int = WebRtcOpus_Encode( |
| 105 kMaxBytes, bitstream_); | 104 encoder, input_audio.data(), |
| 105 rtc::CheckedDivExact(input_audio.size(), static_cast<size_t>(channels_)), |
| 106 kMaxBytes, bitstream_); |
| 106 EXPECT_GE(encoded_bytes_int, 0); | 107 EXPECT_GE(encoded_bytes_int, 0); |
| 107 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int); | 108 encoded_bytes_ = static_cast<size_t>(encoded_bytes_int); |
| 108 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); | 109 int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); |
| 109 int act_len = WebRtcOpus_Decode(decoder, bitstream_, | 110 int act_len = WebRtcOpus_Decode(decoder, bitstream_, |
| 110 encoded_bytes_, output_audio, | 111 encoded_bytes_, output_audio, |
| 111 audio_type); | 112 audio_type); |
| 112 EXPECT_EQ(est_len, act_len); | 113 EXPECT_EQ(est_len, act_len); |
| 113 return act_len; | 114 return act_len; |
| 114 } | 115 } |
| 115 | 116 |
| 116 // Test if encoder/decoder can enter DTX mode properly and do not enter DTX when | 117 // Test if encoder/decoder can enter DTX mode properly and do not enter DTX when |
| 117 // they should not. This test is signal dependent. | 118 // they should not. This test is signal dependent. |
| 118 void OpusTest::TestDtxEffect(bool dtx) { | 119 void OpusTest::TestDtxEffect(bool dtx) { |
| 119 PrepareSpeechData(channels_, 20, 2000); | 120 PrepareSpeechData(channels_, 20, 2000); |
| 120 | 121 |
| 121 // Create encoder memory. | 122 // Create encoder memory. |
| 122 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, | 123 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, |
| 123 channels_, | 124 channels_, |
| 124 application_)); | 125 application_)); |
| 125 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); | 126 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); |
| 126 | 127 |
| 127 // Set bitrate. | 128 // Set bitrate. |
| 128 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, | 129 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, |
| 129 channels_ == 1 ? 32000 : 64000)); | 130 channels_ == 1 ? 32000 : 64000)); |
| 130 | 131 |
| 131 // Set input audio as silence. | 132 // Set input audio as silence. |
| 132 int16_t* silence = new int16_t[kOpus20msFrameSamples * channels_]; | 133 std::vector<int16_t> silence(kOpus20msFrameSamples * channels_, 0); |
| 133 memset(silence, 0, sizeof(int16_t) * kOpus20msFrameSamples * channels_); | |
| 134 | 134 |
| 135 // Setting DTX. | 135 // Setting DTX. |
| 136 EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) : | 136 EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) : |
| 137 WebRtcOpus_DisableDtx(opus_encoder_)); | 137 WebRtcOpus_DisableDtx(opus_encoder_)); |
| 138 | 138 |
| 139 int16_t audio_type; | 139 int16_t audio_type; |
| 140 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; | 140 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; |
| 141 | 141 |
| 142 for (int i = 0; i < 100; ++i) { | 142 for (int i = 0; i < 100; ++i) { |
| 143 EXPECT_EQ(kOpus20msFrameSamples, | 143 EXPECT_EQ(kOpus20msFrameSamples, |
| 144 static_cast<size_t>(EncodeDecode( | 144 static_cast<size_t>(EncodeDecode( |
| 145 opus_encoder_, speech_data_.GetNextBlock(), | 145 opus_encoder_, speech_data_.GetNextBlock(), opus_decoder_, |
| 146 kOpus20msFrameSamples, opus_decoder_, output_data_decode, | 146 output_data_decode, &audio_type))); |
| 147 &audio_type))); | |
| 148 // If not DTX, it should never enter DTX mode. If DTX, we do not care since | 147 // If not DTX, it should never enter DTX mode. If DTX, we do not care since |
| 149 // whether it enters DTX depends on the signal type. | 148 // whether it enters DTX depends on the signal type. |
| 150 if (!dtx) { | 149 if (!dtx) { |
| 151 EXPECT_GT(encoded_bytes_, 1U); | 150 EXPECT_GT(encoded_bytes_, 1U); |
| 152 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 151 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 153 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 152 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 154 EXPECT_EQ(0, audio_type); // Speech. | 153 EXPECT_EQ(0, audio_type); // Speech. |
| 155 } | 154 } |
| 156 } | 155 } |
| 157 | 156 |
| 158 // We input some silent segments. In DTX mode, the encoder will stop sending. | 157 // We input some silent segments. In DTX mode, the encoder will stop sending. |
| 159 // However, DTX may happen after a while. | 158 // However, DTX may happen after a while. |
| 160 for (int i = 0; i < 30; ++i) { | 159 for (int i = 0; i < 30; ++i) { |
| 161 EXPECT_EQ(kOpus20msFrameSamples, | 160 EXPECT_EQ(kOpus20msFrameSamples, static_cast<size_t>(EncodeDecode( |
| 162 static_cast<size_t>(EncodeDecode( | 161 opus_encoder_, silence, opus_decoder_, |
| 163 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, | 162 output_data_decode, &audio_type))); |
| 164 output_data_decode, &audio_type))); | |
| 165 if (!dtx) { | 163 if (!dtx) { |
| 166 EXPECT_GT(encoded_bytes_, 1U); | 164 EXPECT_GT(encoded_bytes_, 1U); |
| 167 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 165 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 168 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 166 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 169 EXPECT_EQ(0, audio_type); // Speech. | 167 EXPECT_EQ(0, audio_type); // Speech. |
| 170 } else if (encoded_bytes_ == 1) { | 168 } else if (encoded_bytes_ == 1) { |
| 171 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); | 169 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); |
| 172 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); | 170 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); |
| 173 EXPECT_EQ(2, audio_type); // Comfort noise. | 171 EXPECT_EQ(2, audio_type); // Comfort noise. |
| 174 break; | 172 break; |
| 175 } | 173 } |
| 176 } | 174 } |
| 177 | 175 |
| 178 // When Opus is in DTX, it wakes up in a regular basis. It sends two packets, | 176 // When Opus is in DTX, it wakes up in a regular basis. It sends two packets, |
| 179 // one with an arbitrary size and the other of 1-byte, then stops sending for | 177 // one with an arbitrary size and the other of 1-byte, then stops sending for |
| 180 // 19 frames. | 178 // 19 frames. |
| 181 const int cycles = 5; | 179 const int cycles = 5; |
| 182 for (int j = 0; j < cycles; ++j) { | 180 for (int j = 0; j < cycles; ++j) { |
| 183 // DTX mode is maintained 19 frames. | 181 // DTX mode is maintained 19 frames. |
| 184 for (int i = 0; i < 19; ++i) { | 182 for (int i = 0; i < 19; ++i) { |
| 185 EXPECT_EQ(kOpus20msFrameSamples, | 183 EXPECT_EQ(kOpus20msFrameSamples, |
| 186 static_cast<size_t>(EncodeDecode( | 184 static_cast<size_t>( |
| 187 opus_encoder_, silence, kOpus20msFrameSamples, | 185 EncodeDecode(opus_encoder_, silence, opus_decoder_, |
| 188 opus_decoder_, output_data_decode, &audio_type))); | 186 output_data_decode, &audio_type))); |
| 189 if (dtx) { | 187 if (dtx) { |
| 190 EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte. | 188 EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte. |
| 191 << "Opus should have entered DTX mode."; | 189 << "Opus should have entered DTX mode."; |
| 192 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); | 190 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); |
| 193 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); | 191 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); |
| 194 EXPECT_EQ(2, audio_type); // Comfort noise. | 192 EXPECT_EQ(2, audio_type); // Comfort noise. |
| 195 } else { | 193 } else { |
| 196 EXPECT_GT(encoded_bytes_, 1U); | 194 EXPECT_GT(encoded_bytes_, 1U); |
| 197 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 195 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 198 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 196 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 199 EXPECT_EQ(0, audio_type); // Speech. | 197 EXPECT_EQ(0, audio_type); // Speech. |
| 200 } | 198 } |
| 201 } | 199 } |
| 202 | 200 |
| 203 // Quit DTX after 19 frames. | 201 // Quit DTX after 19 frames. |
| 204 EXPECT_EQ(kOpus20msFrameSamples, | 202 EXPECT_EQ(kOpus20msFrameSamples, static_cast<size_t>(EncodeDecode( |
| 205 static_cast<size_t>(EncodeDecode( | 203 opus_encoder_, silence, opus_decoder_, |
| 206 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, | 204 output_data_decode, &audio_type))); |
| 207 output_data_decode, &audio_type))); | |
| 208 | 205 |
| 209 EXPECT_GT(encoded_bytes_, 1U); | 206 EXPECT_GT(encoded_bytes_, 1U); |
| 210 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 207 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 211 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 208 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 212 EXPECT_EQ(0, audio_type); // Speech. | 209 EXPECT_EQ(0, audio_type); // Speech. |
| 213 | 210 |
| 214 // Enters DTX again immediately. | 211 // Enters DTX again immediately. |
| 215 EXPECT_EQ(kOpus20msFrameSamples, | 212 EXPECT_EQ(kOpus20msFrameSamples, static_cast<size_t>(EncodeDecode( |
| 216 static_cast<size_t>(EncodeDecode( | 213 opus_encoder_, silence, opus_decoder_, |
| 217 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, | 214 output_data_decode, &audio_type))); |
| 218 output_data_decode, &audio_type))); | |
| 219 if (dtx) { | 215 if (dtx) { |
| 220 EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte. | 216 EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte. |
| 221 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); | 217 EXPECT_EQ(1, opus_encoder_->in_dtx_mode); |
| 222 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); | 218 EXPECT_EQ(1, opus_decoder_->in_dtx_mode); |
| 223 EXPECT_EQ(2, audio_type); // Comfort noise. | 219 EXPECT_EQ(2, audio_type); // Comfort noise. |
| 224 } else { | 220 } else { |
| 225 EXPECT_GT(encoded_bytes_, 1U); | 221 EXPECT_GT(encoded_bytes_, 1U); |
| 226 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 222 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 227 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 223 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 228 EXPECT_EQ(0, audio_type); // Speech. | 224 EXPECT_EQ(0, audio_type); // Speech. |
| 229 } | 225 } |
| 230 } | 226 } |
| 231 | 227 |
| 232 silence[0] = 10000; | 228 silence[0] = 10000; |
| 233 if (dtx) { | 229 if (dtx) { |
| 234 // Verify that encoder/decoder can jump out from DTX mode. | 230 // Verify that encoder/decoder can jump out from DTX mode. |
| 235 EXPECT_EQ(kOpus20msFrameSamples, | 231 EXPECT_EQ(kOpus20msFrameSamples, static_cast<size_t>(EncodeDecode( |
| 236 static_cast<size_t>(EncodeDecode( | 232 opus_encoder_, silence, opus_decoder_, |
| 237 opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, | 233 output_data_decode, &audio_type))); |
| 238 output_data_decode, &audio_type))); | |
| 239 EXPECT_GT(encoded_bytes_, 1U); | 234 EXPECT_GT(encoded_bytes_, 1U); |
| 240 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); | 235 EXPECT_EQ(0, opus_encoder_->in_dtx_mode); |
| 241 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); | 236 EXPECT_EQ(0, opus_decoder_->in_dtx_mode); |
| 242 EXPECT_EQ(0, audio_type); // Speech. | 237 EXPECT_EQ(0, audio_type); // Speech. |
| 243 } | 238 } |
| 244 | 239 |
| 245 // Free memory. | 240 // Free memory. |
| 246 delete[] output_data_decode; | 241 delete[] output_data_decode; |
| 247 delete[] silence; | |
| 248 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 242 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 249 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 243 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
| 250 } | 244 } |
| 251 | 245 |
| 252 // Test failing Create. | 246 // Test failing Create. |
| 253 TEST(OpusTest, OpusCreateFail) { | 247 TEST(OpusTest, OpusCreateFail) { |
| 254 WebRtcOpusEncInst* opus_encoder; | 248 WebRtcOpusEncInst* opus_encoder; |
| 255 WebRtcOpusDecInst* opus_decoder; | 249 WebRtcOpusDecInst* opus_decoder; |
| 256 | 250 |
| 257 // Test to see that an invalid pointer is caught. | 251 // Test to see that an invalid pointer is caught. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 opus_int32 app; | 301 opus_int32 app; |
| 308 opus_encoder_ctl(opus_encoder_->encoder, | 302 opus_encoder_ctl(opus_encoder_->encoder, |
| 309 OPUS_GET_APPLICATION(&app)); | 303 OPUS_GET_APPLICATION(&app)); |
| 310 EXPECT_EQ(application_ == 0 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, | 304 EXPECT_EQ(application_ == 0 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, |
| 311 app); | 305 app); |
| 312 | 306 |
| 313 // Encode & decode. | 307 // Encode & decode. |
| 314 int16_t audio_type; | 308 int16_t audio_type; |
| 315 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; | 309 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; |
| 316 EXPECT_EQ(kOpus20msFrameSamples, | 310 EXPECT_EQ(kOpus20msFrameSamples, |
| 317 static_cast<size_t>(EncodeDecode( | 311 static_cast<size_t>( |
| 318 opus_encoder_, speech_data_.GetNextBlock(), | 312 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(), |
| 319 kOpus20msFrameSamples, opus_decoder_, output_data_decode, | 313 opus_decoder_, output_data_decode, &audio_type))); |
| 320 &audio_type))); | |
| 321 | 314 |
| 322 // Free memory. | 315 // Free memory. |
| 323 delete[] output_data_decode; | 316 delete[] output_data_decode; |
| 324 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 317 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 325 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 318 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
| 326 } | 319 } |
| 327 | 320 |
| 328 TEST_P(OpusTest, OpusSetBitRate) { | 321 TEST_P(OpusTest, OpusSetBitRate) { |
| 329 // Test without creating encoder memory. | 322 // Test without creating encoder memory. |
| 330 EXPECT_EQ(-1, WebRtcOpus_SetBitRate(opus_encoder_, 60000)); | 323 EXPECT_EQ(-1, WebRtcOpus_SetBitRate(opus_encoder_, 60000)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 // Create encoder memory. | 360 // Create encoder memory. |
| 368 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, | 361 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, |
| 369 channels_, | 362 channels_, |
| 370 application_)); | 363 application_)); |
| 371 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); | 364 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); |
| 372 | 365 |
| 373 // Encode & decode. | 366 // Encode & decode. |
| 374 int16_t audio_type; | 367 int16_t audio_type; |
| 375 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; | 368 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; |
| 376 EXPECT_EQ(kOpus20msFrameSamples, | 369 EXPECT_EQ(kOpus20msFrameSamples, |
| 377 static_cast<size_t>(EncodeDecode( | 370 static_cast<size_t>( |
| 378 opus_encoder_, speech_data_.GetNextBlock(), | 371 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(), |
| 379 kOpus20msFrameSamples, opus_decoder_, output_data_decode, | 372 opus_decoder_, output_data_decode, &audio_type))); |
| 380 &audio_type))); | |
| 381 | 373 |
| 382 WebRtcOpus_DecoderInit(opus_decoder_); | 374 WebRtcOpus_DecoderInit(opus_decoder_); |
| 383 | 375 |
| 384 EXPECT_EQ(kOpus20msFrameSamples, | 376 EXPECT_EQ(kOpus20msFrameSamples, |
| 385 static_cast<size_t>(WebRtcOpus_Decode( | 377 static_cast<size_t>(WebRtcOpus_Decode( |
| 386 opus_decoder_, bitstream_, encoded_bytes_, output_data_decode, | 378 opus_decoder_, bitstream_, encoded_bytes_, output_data_decode, |
| 387 &audio_type))); | 379 &audio_type))); |
| 388 | 380 |
| 389 // Free memory. | 381 // Free memory. |
| 390 delete[] output_data_decode; | 382 delete[] output_data_decode; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, | 498 EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, |
| 507 channels_== 1 ? 32000 : 64000)); | 499 channels_== 1 ? 32000 : 64000)); |
| 508 | 500 |
| 509 // Check number of channels for decoder. | 501 // Check number of channels for decoder. |
| 510 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_)); | 502 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_)); |
| 511 | 503 |
| 512 // Encode & decode. | 504 // Encode & decode. |
| 513 int16_t audio_type; | 505 int16_t audio_type; |
| 514 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; | 506 int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; |
| 515 EXPECT_EQ(kOpus20msFrameSamples, | 507 EXPECT_EQ(kOpus20msFrameSamples, |
| 516 static_cast<size_t>(EncodeDecode( | 508 static_cast<size_t>( |
| 517 opus_encoder_, speech_data_.GetNextBlock(), | 509 EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(), |
| 518 kOpus20msFrameSamples, opus_decoder_, output_data_decode, | 510 opus_decoder_, output_data_decode, &audio_type))); |
| 519 &audio_type))); | |
| 520 | 511 |
| 521 // Call decoder PLC. | 512 // Call decoder PLC. |
| 522 int16_t* plc_buffer = new int16_t[kOpus20msFrameSamples * channels_]; | 513 int16_t* plc_buffer = new int16_t[kOpus20msFrameSamples * channels_]; |
| 523 EXPECT_EQ(kOpus20msFrameSamples, | 514 EXPECT_EQ(kOpus20msFrameSamples, |
| 524 static_cast<size_t>(WebRtcOpus_DecodePlc( | 515 static_cast<size_t>(WebRtcOpus_DecodePlc( |
| 525 opus_decoder_, plc_buffer, 1))); | 516 opus_decoder_, plc_buffer, 1))); |
| 526 | 517 |
| 527 // Free memory. | 518 // Free memory. |
| 528 delete[] plc_buffer; | 519 delete[] plc_buffer; |
| 529 delete[] output_data_decode; | 520 delete[] output_data_decode; |
| 530 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 521 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 531 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 522 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
| 532 } | 523 } |
| 533 | 524 |
| 534 // Duration estimation. | 525 // Duration estimation. |
| 535 TEST_P(OpusTest, OpusDurationEstimation) { | 526 TEST_P(OpusTest, OpusDurationEstimation) { |
| 536 PrepareSpeechData(channels_, 20, 20); | 527 PrepareSpeechData(channels_, 20, 20); |
| 537 | 528 |
| 538 // Create. | 529 // Create. |
| 539 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, | 530 EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, |
| 540 channels_, | 531 channels_, |
| 541 application_)); | 532 application_)); |
| 542 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); | 533 EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); |
| 543 | 534 |
| 544 // 10 ms. We use only first 10 ms of a 20 ms block. | 535 // 10 ms. We use only first 10 ms of a 20 ms block. |
| 545 int encoded_bytes_int = WebRtcOpus_Encode(opus_encoder_, | 536 auto speech_block = speech_data_.GetNextBlock(); |
| 546 speech_data_.GetNextBlock(), | 537 int encoded_bytes_int = WebRtcOpus_Encode( |
| 547 kOpus10msFrameSamples, | 538 opus_encoder_, speech_block.data(), |
| 548 kMaxBytes, bitstream_); | 539 rtc::CheckedDivExact(speech_block.size(), |
| 540 2 * static_cast<size_t>(channels_)), |
| 541 kMaxBytes, bitstream_); |
| 549 EXPECT_GE(encoded_bytes_int, 0); | 542 EXPECT_GE(encoded_bytes_int, 0); |
| 550 EXPECT_EQ(kOpus10msFrameSamples, | 543 EXPECT_EQ(kOpus10msFrameSamples, |
| 551 static_cast<size_t>(WebRtcOpus_DurationEst( | 544 static_cast<size_t>(WebRtcOpus_DurationEst( |
| 552 opus_decoder_, bitstream_, | 545 opus_decoder_, bitstream_, |
| 553 static_cast<size_t>(encoded_bytes_int)))); | 546 static_cast<size_t>(encoded_bytes_int)))); |
| 554 | 547 |
| 555 // 20 ms | 548 // 20 ms |
| 556 encoded_bytes_int = WebRtcOpus_Encode(opus_encoder_, | 549 speech_block = speech_data_.GetNextBlock(); |
| 557 speech_data_.GetNextBlock(), | 550 encoded_bytes_int = WebRtcOpus_Encode( |
| 558 kOpus20msFrameSamples, | 551 opus_encoder_, speech_block.data(), |
| 559 kMaxBytes, bitstream_); | 552 rtc::CheckedDivExact(speech_block.size(), static_cast<size_t>(channels_)), |
| 553 kMaxBytes, bitstream_); |
| 560 EXPECT_GE(encoded_bytes_int, 0); | 554 EXPECT_GE(encoded_bytes_int, 0); |
| 561 EXPECT_EQ(kOpus20msFrameSamples, | 555 EXPECT_EQ(kOpus20msFrameSamples, |
| 562 static_cast<size_t>(WebRtcOpus_DurationEst( | 556 static_cast<size_t>(WebRtcOpus_DurationEst( |
| 563 opus_decoder_, bitstream_, | 557 opus_decoder_, bitstream_, |
| 564 static_cast<size_t>(encoded_bytes_int)))); | 558 static_cast<size_t>(encoded_bytes_int)))); |
| 565 | 559 |
| 566 // Free memory. | 560 // Free memory. |
| 567 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 561 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 568 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 562 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
| 569 } | 563 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 587 // Check number of channels for decoder. | 581 // Check number of channels for decoder. |
| 588 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_)); | 582 EXPECT_EQ(channels_, WebRtcOpus_DecoderChannels(opus_decoder_)); |
| 589 | 583 |
| 590 // Encode & decode. | 584 // Encode & decode. |
| 591 int16_t audio_type; | 585 int16_t audio_type; |
| 592 rtc::scoped_ptr<int16_t[]> output_data_decode( | 586 rtc::scoped_ptr<int16_t[]> output_data_decode( |
| 593 new int16_t[kPackets * kOpus20msFrameSamples * channels_]); | 587 new int16_t[kPackets * kOpus20msFrameSamples * channels_]); |
| 594 OpusRepacketizer* rp = opus_repacketizer_create(); | 588 OpusRepacketizer* rp = opus_repacketizer_create(); |
| 595 | 589 |
| 596 for (int idx = 0; idx < kPackets; idx++) { | 590 for (int idx = 0; idx < kPackets; idx++) { |
| 597 encoded_bytes_ = WebRtcOpus_Encode(opus_encoder_, | 591 auto speech_block = speech_data_.GetNextBlock(); |
| 598 speech_data_.GetNextBlock(), | 592 encoded_bytes_ = |
| 599 kOpus20msFrameSamples, kMaxBytes, | 593 WebRtcOpus_Encode(opus_encoder_, speech_block.data(), |
| 600 bitstream_); | 594 rtc::CheckedDivExact(speech_block.size(), |
| 595 static_cast<size_t>(channels_)), |
| 596 kMaxBytes, bitstream_); |
| 601 EXPECT_EQ(OPUS_OK, opus_repacketizer_cat(rp, bitstream_, encoded_bytes_)); | 597 EXPECT_EQ(OPUS_OK, opus_repacketizer_cat(rp, bitstream_, encoded_bytes_)); |
| 602 } | 598 } |
| 603 | 599 |
| 604 encoded_bytes_ = opus_repacketizer_out(rp, bitstream_, kMaxBytes); | 600 encoded_bytes_ = opus_repacketizer_out(rp, bitstream_, kMaxBytes); |
| 605 | 601 |
| 606 EXPECT_EQ(kOpus20msFrameSamples * kPackets, | 602 EXPECT_EQ(kOpus20msFrameSamples * kPackets, |
| 607 static_cast<size_t>(WebRtcOpus_DurationEst( | 603 static_cast<size_t>(WebRtcOpus_DurationEst( |
| 608 opus_decoder_, bitstream_, encoded_bytes_))); | 604 opus_decoder_, bitstream_, encoded_bytes_))); |
| 609 | 605 |
| 610 EXPECT_EQ(kOpus20msFrameSamples * kPackets, | 606 EXPECT_EQ(kOpus20msFrameSamples * kPackets, |
| 611 static_cast<size_t>(WebRtcOpus_Decode( | 607 static_cast<size_t>(WebRtcOpus_Decode( |
| 612 opus_decoder_, bitstream_, encoded_bytes_, | 608 opus_decoder_, bitstream_, encoded_bytes_, |
| 613 output_data_decode.get(), &audio_type))); | 609 output_data_decode.get(), &audio_type))); |
| 614 | 610 |
| 615 // Free memory. | 611 // Free memory. |
| 616 opus_repacketizer_destroy(rp); | 612 opus_repacketizer_destroy(rp); |
| 617 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); | 613 EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); |
| 618 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); | 614 EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); |
| 619 } | 615 } |
| 620 | 616 |
| 621 INSTANTIATE_TEST_CASE_P(VariousMode, | 617 INSTANTIATE_TEST_CASE_P(VariousMode, |
| 622 OpusTest, | 618 OpusTest, |
| 623 Combine(Values(1, 2), Values(0, 1))); | 619 Combine(Values(1, 2), Values(0, 1))); |
| 624 | 620 |
| 625 | 621 |
| 626 } // namespace webrtc | 622 } // namespace webrtc |
| OLD | NEW |