Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This test generate synthetic data. For audio it's a sinusoid waveform with | 5 // This test generate synthetic data. For audio it's a sinusoid waveform with |
| 6 // frequency kSoundFrequency and different amplitudes. For video it's a pattern | 6 // frequency kSoundFrequency and different amplitudes. For video it's a pattern |
| 7 // that is shifting by one pixel per frame, each pixels neighbors right and down | 7 // that is shifting by one pixel per frame, each pixels neighbors right and down |
| 8 // is this pixels value +1, since the pixel value is 8 bit it will wrap | 8 // is this pixels value +1, since the pixel value is 8 bit it will wrap |
| 9 // frequently within the image. Visually this will create diagonally color bands | 9 // frequently within the image. Visually this will create diagonally color bands |
| 10 // that moves across the screen | 10 // that moves across the screen |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 } | 192 } |
| 193 | 193 |
| 194 // Computes the SNR based on the error between |reference_audio_frame| and | 194 // Computes the SNR based on the error between |reference_audio_frame| and |
| 195 // |output_audio_frame| given a sample offset of |delay|. | 195 // |output_audio_frame| given a sample offset of |delay|. |
| 196 double ComputeSNR(const PcmAudioFrame& reference_audio_frame, | 196 double ComputeSNR(const PcmAudioFrame& reference_audio_frame, |
| 197 const std::vector<int16>& output_audio_samples, | 197 const std::vector<int16>& output_audio_samples, |
| 198 size_t delay) { | 198 size_t delay) { |
| 199 // Check all out allowed delays. | 199 // Check all out allowed delays. |
| 200 double square_error = 0; | 200 double square_error = 0; |
| 201 double variance = 0; | 201 double variance = 0; |
| 202 | |
|
Alpha Left Google
2013/11/07 01:10:11
nit: please don't fix style in a functional CL in
pwestin
2013/11/07 17:16:04
Done.
| |
| 202 for (size_t i = 0; i < reference_audio_frame.samples.size() - delay; ++i) { | 203 for (size_t i = 0; i < reference_audio_frame.samples.size() - delay; ++i) { |
| 203 size_t error = reference_audio_frame.samples[i] - | 204 size_t error = reference_audio_frame.samples[i] - |
| 204 output_audio_samples[i + delay]; | 205 output_audio_samples[i + delay]; |
| 205 | 206 |
| 206 square_error += error * error; | 207 square_error += error * error; |
| 207 variance += reference_audio_frame.samples[i] * | 208 variance += reference_audio_frame.samples[i] * |
| 208 reference_audio_frame.samples[i]; | 209 reference_audio_frame.samples[i]; |
| 209 } | 210 } |
| 210 // 16-bit audio has a dynamic range of 96 dB. | 211 // 16-bit audio has a dynamic range of 96 dB. |
| 211 double snr = 96.0; // Assigning 96 dB to the zero-error case. | 212 double snr = 96.0; // Assigning 96 dB to the zero-error case. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 240 return best_snr; | 241 return best_snr; |
| 241 } | 242 } |
| 242 | 243 |
| 243 void CheckPcmAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, | 244 void CheckPcmAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, |
| 244 const base::TimeTicks& playout_time) { | 245 const base::TimeTicks& playout_time) { |
| 245 ++num_called_; | 246 ++num_called_; |
| 246 | 247 |
| 247 CheckBasicAudioFrame(audio_frame, playout_time); | 248 CheckBasicAudioFrame(audio_frame, playout_time); |
| 248 ExpectedAudioFrame expected_audio_frame = expected_frame_.front(); | 249 ExpectedAudioFrame expected_audio_frame = expected_frame_.front(); |
| 249 expected_frame_.pop_front(); | 250 expected_frame_.pop_front(); |
| 251 | |
| 250 if (audio_frame->samples.size() == 0) return; // No more checks needed. | 252 if (audio_frame->samples.size() == 0) return; // No more checks needed. |
| 251 | 253 |
| 252 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000, | 254 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000, |
| 253 expected_audio_frame.audio_frame.channels); | 255 expected_audio_frame.audio_frame.channels); |
| 254 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame, | 256 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame, |
| 255 audio_frame->samples, max_delay), | 257 audio_frame->samples, max_delay), |
| 256 expected_min_snr_); | 258 expected_min_snr_); |
| 257 } | 259 } |
| 258 | 260 |
| 259 void CheckCodedPcmAudioFrame(scoped_ptr<EncodedAudioFrame> audio_frame, | 261 void CheckCodedPcmAudioFrame(scoped_ptr<EncodedAudioFrame> audio_frame, |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 277 if (audio_frame->data.size() == 0) return; // No more checks needed. | 279 if (audio_frame->data.size() == 0) return; // No more checks needed. |
| 278 | 280 |
| 279 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000, | 281 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000, |
| 280 expected_audio_frame.audio_frame.channels); | 282 expected_audio_frame.audio_frame.channels); |
| 281 | 283 |
| 282 // We need to convert our "coded" audio frame to our raw format. | 284 // We need to convert our "coded" audio frame to our raw format. |
| 283 std::vector<int16> output_audio_samples; | 285 std::vector<int16> output_audio_samples; |
| 284 size_t number_of_samples = audio_frame->data.size() / 2; | 286 size_t number_of_samples = audio_frame->data.size() / 2; |
| 285 | 287 |
| 286 for (size_t i = 0; i < number_of_samples; ++i) { | 288 for (size_t i = 0; i < number_of_samples; ++i) { |
| 287 uint16 sample = (audio_frame->data[1 + i * sizeof(uint16)]) + | 289 uint16 sample = |
| 288 (static_cast<uint16>(audio_frame->data[i * sizeof(uint16)]) << 8); | 290 static_cast<uint8>(audio_frame->data[1 + i * sizeof(uint16)]) + |
| 291 (static_cast<uint16>(audio_frame->data[i * sizeof(uint16)]) << 8); | |
| 289 output_audio_samples.push_back(static_cast<int16>(sample)); | 292 output_audio_samples.push_back(static_cast<int16>(sample)); |
| 290 } | 293 } |
| 291 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame, | 294 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame, |
| 292 output_audio_samples, max_delay), | 295 output_audio_samples, max_delay), |
| 293 expected_min_snr_); | 296 expected_min_snr_); |
| 294 } | 297 } |
| 295 | 298 |
| 296 int number_times_called() { | 299 int number_times_called() { |
| 297 EXPECT_GE(avg_snr_, expected_avg_snr_); | 300 EXPECT_GE(avg_snr_, expected_avg_snr_); |
| 298 return num_called_; | 301 return num_called_; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 }; | 537 }; |
| 535 | 538 |
| 536 // Audio and video test without packet loss using raw PCM 16 audio "codec"; | 539 // Audio and video test without packet loss using raw PCM 16 audio "codec"; |
| 537 // note: even though the audio is not coded it is still re-sampled between | 540 // note: even though the audio is not coded it is still re-sampled between |
| 538 // 48 and 32 KHz. | 541 // 48 and 32 KHz. |
| 539 TEST_F(End2EndTest, LoopNoLossPcm16) { | 542 TEST_F(End2EndTest, LoopNoLossPcm16) { |
| 540 // Note running codec in different sampling frequency. | 543 // Note running codec in different sampling frequency. |
| 541 SetupConfig(kPcm16, 32000, false, 1); | 544 SetupConfig(kPcm16, 32000, false, 1); |
| 542 Create(); | 545 Create(); |
| 543 test_receiver_audio_callback_->SetExpectedResult(kAudioSamplingFrequency, 20, | 546 test_receiver_audio_callback_->SetExpectedResult(kAudioSamplingFrequency, 20, |
| 544 25); | 547 20); |
| 545 | 548 |
| 546 int video_start = 1; | 549 int video_start = 1; |
| 547 int audio_diff = kFrameTimerMs; | 550 int audio_diff = kFrameTimerMs; |
| 548 int i = 0; | 551 int i = 0; |
| 549 | 552 |
| 550 std::cout << "Progress "; | 553 std::cout << "Progress "; |
| 551 for (; i < 100; ++i) { | 554 for (; i < 100; ++i) { |
| 552 int num_10ms_blocks = audio_diff / 10; | 555 int num_10ms_blocks = audio_diff / 10; |
| 553 audio_diff -= num_10ms_blocks * 10; | 556 audio_diff -= num_10ms_blocks * 10; |
| 554 base::TimeTicks send_time = testing_clock_.NowTicks(); | 557 base::TimeTicks send_time = testing_clock_.NowTicks(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 855 frame_receiver_->GetRawVideoFrame( | 858 frame_receiver_->GetRawVideoFrame( |
| 856 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 859 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 857 test_receiver_video_callback_)); | 860 test_receiver_video_callback_)); |
| 858 RunTasks(kFrameTimerMs); | 861 RunTasks(kFrameTimerMs); |
| 859 } | 862 } |
| 860 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 863 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 861 EXPECT_EQ(frames_counter, | 864 EXPECT_EQ(frames_counter, |
| 862 test_receiver_video_callback_->number_times_called()); | 865 test_receiver_video_callback_->number_times_called()); |
| 863 } | 866 } |
| 864 | 867 |
| 868 TEST_F(End2EndTest, CryptoVideo) { | |
| 869 SetupConfig(kPcm16, 32000, false, 1); | |
| 870 | |
| 871 video_sender_config_.aes_iv_mask = "1234567890abcdeffedcba0987654321"; | |
| 872 video_sender_config_.aes_key = "deadbeefcafeb0b0b0b0cafedeadbeef"; | |
| 873 | |
| 874 video_receiver_config_.aes_iv_mask = video_sender_config_.aes_iv_mask; | |
| 875 video_receiver_config_.aes_key = video_sender_config_.aes_key; | |
| 876 | |
| 877 Create(); | |
| 878 | |
| 879 int frames_counter = 0; | |
| 880 for (; frames_counter < 20; ++frames_counter) { | |
| 881 const base::TimeTicks send_time = testing_clock_.NowTicks(); | |
| 882 | |
| 883 SendVideoFrame(frames_counter, send_time); | |
| 884 | |
| 885 test_receiver_video_callback_->AddExpectedResult(frames_counter, | |
| 886 video_sender_config_.width, video_sender_config_.height, send_time); | |
| 887 | |
| 888 // GetRawVideoFrame will not return the frame until we are close to the | |
| 889 // time in which we should render the frame. | |
| 890 frame_receiver_->GetRawVideoFrame( | |
| 891 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | |
| 892 test_receiver_video_callback_)); | |
| 893 RunTasks(kFrameTimerMs); | |
| 894 } | |
| 895 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | |
| 896 EXPECT_EQ(frames_counter, | |
| 897 test_receiver_video_callback_->number_times_called()); | |
| 898 } | |
| 899 | |
| 900 | |
| 901 TEST_F(End2EndTest, CryptoAudio) { | |
| 902 SetupConfig(kPcm16, 32000, false, 1); | |
| 903 | |
| 904 audio_sender_config_.aes_iv_mask = "abcdeffedcba12345678900987654321"; | |
| 905 audio_sender_config_.aes_key = "deadbeefcafecafedeadbeefb0b0b0b0"; | |
| 906 | |
| 907 audio_receiver_config_.aes_iv_mask = audio_sender_config_.aes_iv_mask; | |
| 908 audio_receiver_config_.aes_key = audio_sender_config_.aes_key; | |
| 909 | |
| 910 Create(); | |
| 911 test_receiver_audio_callback_->SetExpectedResult(32000, 18, 20); | |
| 912 | |
| 913 int frames_counter = 0; | |
| 914 for (; frames_counter < 20; ++frames_counter) { | |
| 915 int num_10ms_blocks = 2; | |
| 916 | |
| 917 const base::TimeTicks send_time = testing_clock_.NowTicks(); | |
| 918 | |
| 919 PcmAudioFrame* audio_frame = CreateAudioFrame(num_10ms_blocks, | |
| 920 kSoundFrequency, 32000); | |
| 921 | |
| 922 if (frames_counter != 0) { | |
| 923 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 924 // first samples will be 0 and then slowly ramp up to its real amplitude; | |
| 925 // ignore the first frame. | |
| 926 test_receiver_audio_callback_->AddExpectedResult(audio_frame, | |
| 927 num_10ms_blocks, send_time); | |
| 928 } | |
| 929 frame_input_->InsertRawAudioFrame(audio_frame, send_time, | |
| 930 base::Bind(FrameInput::DeleteAudioFrame, audio_frame)); | |
| 931 | |
| 932 RunTasks(num_10ms_blocks * 10); | |
| 933 | |
| 934 if (frames_counter == 0) { | |
| 935 frame_receiver_->GetRawAudioFrame(num_10ms_blocks, | |
| 936 32000, | |
| 937 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 938 test_receiver_audio_callback_)); | |
| 939 } else { | |
| 940 frame_receiver_->GetRawAudioFrame(num_10ms_blocks, | |
| 941 32000, | |
| 942 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 943 test_receiver_audio_callback_)); | |
| 944 } | |
| 945 } | |
| 946 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | |
| 947 EXPECT_EQ(frames_counter - 1, | |
| 948 test_receiver_audio_callback_->number_times_called()); | |
| 949 } | |
| 950 | |
| 951 | |
| 952 | |
| 865 // TODO(pwestin): Add repeatable packet loss test. | 953 // TODO(pwestin): Add repeatable packet loss test. |
| 866 // TODO(pwestin): Add test for misaligned send get calls. | 954 // TODO(pwestin): Add test for misaligned send get calls. |
| 867 // TODO(pwestin): Add more tests that does not resample. | 955 // TODO(pwestin): Add more tests that does not resample. |
| 868 // TODO(pwestin): Add test when we have starvation for our RunTask. | 956 // TODO(pwestin): Add test when we have starvation for our RunTask. |
| 869 | 957 |
| 870 } // namespace cast | 958 } // namespace cast |
| 871 } // namespace media | 959 } // namespace media |
| OLD | NEW |