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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 if (audio_frame->data.size() == 0) return; // No more checks needed. | 277 if (audio_frame->data.size() == 0) return; // No more checks needed. |
| 278 | 278 |
| 279 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000, | 279 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000, |
| 280 expected_audio_frame.audio_frame.channels); | 280 expected_audio_frame.audio_frame.channels); |
| 281 | 281 |
| 282 // We need to convert our "coded" audio frame to our raw format. | 282 // We need to convert our "coded" audio frame to our raw format. |
| 283 std::vector<int16> output_audio_samples; | 283 std::vector<int16> output_audio_samples; |
| 284 size_t number_of_samples = audio_frame->data.size() / 2; | 284 size_t number_of_samples = audio_frame->data.size() / 2; |
| 285 | 285 |
| 286 for (size_t i = 0; i < number_of_samples; ++i) { | 286 for (size_t i = 0; i < number_of_samples; ++i) { |
| 287 uint16 sample = (audio_frame->data[1 + i * sizeof(uint16)]) + | 287 uint16 sample = |
| 288 (static_cast<uint16>(audio_frame->data[i * sizeof(uint16)]) << 8); | 288 static_cast<uint8>(audio_frame->data[1 + i * sizeof(uint16)]) + |
| 289 (static_cast<uint16>(audio_frame->data[i * sizeof(uint16)]) << 8); | |
| 289 output_audio_samples.push_back(static_cast<int16>(sample)); | 290 output_audio_samples.push_back(static_cast<int16>(sample)); |
| 290 } | 291 } |
| 291 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame, | 292 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame, |
| 292 output_audio_samples, max_delay), | 293 output_audio_samples, max_delay), |
| 293 expected_min_snr_); | 294 expected_min_snr_); |
| 294 } | 295 } |
| 295 | 296 |
| 296 int number_times_called() { | 297 int number_times_called() { |
| 297 EXPECT_GE(avg_snr_, expected_avg_snr_); | 298 EXPECT_GE(avg_snr_, expected_avg_snr_); |
| 298 return num_called_; | 299 return num_called_; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 } | 504 } |
| 504 | 505 |
| 505 void RunTasks(int during_ms) { | 506 void RunTasks(int during_ms) { |
| 506 for (int i = 0; i < during_ms; ++i) { | 507 for (int i = 0; i < during_ms; ++i) { |
| 507 // Call process the timers every 1 ms. | 508 // Call process the timers every 1 ms. |
| 508 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); | 509 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); |
| 509 task_runner_->RunTasks(); | 510 task_runner_->RunTasks(); |
| 510 } | 511 } |
| 511 } | 512 } |
| 512 | 513 |
| 514 char ConvertFromBase16Char(char base_16) { | |
|
Alpha Left Google
2013/11/08 22:40:02
Can you put this in a helper source file?
pwestin
2013/11/12 22:07:23
Done.
| |
| 515 DCHECK((base_16 >= '0' && base_16 <= '9') || | |
| 516 (base_16 >= 'a' && base_16 <= 'f') || | |
| 517 (base_16 >= 'A' && base_16 <= 'F')); | |
| 518 | |
| 519 if (base_16 >= '0' && base_16 <= '9') { | |
| 520 return base_16 - '0'; | |
| 521 } | |
| 522 if (base_16 >= 'a' && base_16 <= 'f') { | |
| 523 return base_16 - 'a' + 10; | |
| 524 } | |
| 525 return base_16 - 'A' + 10; | |
| 526 } | |
| 527 | |
| 528 std::string ConvertFromBase16String(const std::string base_16) { | |
| 529 std::string compressed; | |
| 530 DCHECK(base_16.size() % 2 == 0) << "Must be a multiple of 2"; | |
| 531 compressed.reserve(base_16.size() / 2); | |
| 532 | |
| 533 for (std::string::const_iterator it = base_16.begin(); it != base_16.end(); | |
| 534 ++it) { | |
| 535 char first_part = ConvertFromBase16Char(*it++); | |
| 536 char second_part = ConvertFromBase16Char(*it); | |
| 537 compressed.push_back((first_part << 4) + second_part); | |
| 538 } | |
| 539 return compressed; | |
| 540 } | |
| 541 | |
| 513 AudioReceiverConfig audio_receiver_config_; | 542 AudioReceiverConfig audio_receiver_config_; |
| 514 VideoReceiverConfig video_receiver_config_; | 543 VideoReceiverConfig video_receiver_config_; |
| 515 AudioSenderConfig audio_sender_config_; | 544 AudioSenderConfig audio_sender_config_; |
| 516 VideoSenderConfig video_sender_config_; | 545 VideoSenderConfig video_sender_config_; |
| 517 | 546 |
| 518 base::SimpleTestTickClock testing_clock_; | 547 base::SimpleTestTickClock testing_clock_; |
| 519 scoped_refptr<test::FakeTaskRunner> task_runner_; | 548 scoped_refptr<test::FakeTaskRunner> task_runner_; |
| 520 scoped_refptr<CastEnvironment> cast_environment_; | 549 scoped_refptr<CastEnvironment> cast_environment_; |
| 521 | 550 |
| 522 LoopBackTransport sender_to_receiver_; | 551 LoopBackTransport sender_to_receiver_; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 534 }; | 563 }; |
| 535 | 564 |
| 536 // Audio and video test without packet loss using raw PCM 16 audio "codec"; | 565 // 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 | 566 // note: even though the audio is not coded it is still re-sampled between |
| 538 // 48 and 32 KHz. | 567 // 48 and 32 KHz. |
| 539 TEST_F(End2EndTest, LoopNoLossPcm16) { | 568 TEST_F(End2EndTest, LoopNoLossPcm16) { |
| 540 // Note running codec in different sampling frequency. | 569 // Note running codec in different sampling frequency. |
| 541 SetupConfig(kPcm16, 32000, false, 1); | 570 SetupConfig(kPcm16, 32000, false, 1); |
| 542 Create(); | 571 Create(); |
| 543 test_receiver_audio_callback_->SetExpectedResult(kAudioSamplingFrequency, 20, | 572 test_receiver_audio_callback_->SetExpectedResult(kAudioSamplingFrequency, 20, |
| 544 25); | 573 20); |
| 545 | 574 |
| 546 int video_start = 1; | 575 int video_start = 1; |
| 547 int audio_diff = kFrameTimerMs; | 576 int audio_diff = kFrameTimerMs; |
| 548 int i = 0; | 577 int i = 0; |
| 549 | 578 |
| 550 std::cout << "Progress "; | 579 std::cout << "Progress "; |
| 551 for (; i < 100; ++i) { | 580 for (; i < 100; ++i) { |
| 552 int num_10ms_blocks = audio_diff / 10; | 581 int num_10ms_blocks = audio_diff / 10; |
| 553 audio_diff -= num_10ms_blocks * 10; | 582 audio_diff -= num_10ms_blocks * 10; |
| 554 base::TimeTicks send_time = testing_clock_.NowTicks(); | 583 base::TimeTicks send_time = testing_clock_.NowTicks(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 855 frame_receiver_->GetRawVideoFrame( | 884 frame_receiver_->GetRawVideoFrame( |
| 856 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 885 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 857 test_receiver_video_callback_)); | 886 test_receiver_video_callback_)); |
| 858 RunTasks(kFrameTimerMs); | 887 RunTasks(kFrameTimerMs); |
| 859 } | 888 } |
| 860 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 889 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 861 EXPECT_EQ(frames_counter, | 890 EXPECT_EQ(frames_counter, |
| 862 test_receiver_video_callback_->number_times_called()); | 891 test_receiver_video_callback_->number_times_called()); |
| 863 } | 892 } |
| 864 | 893 |
| 894 TEST_F(End2EndTest, CryptoVideo) { | |
| 895 SetupConfig(kPcm16, 32000, false, 1); | |
| 896 | |
| 897 video_sender_config_.aes_iv_mask = | |
| 898 ConvertFromBase16String("1234567890abcdeffedcba0987654321"); | |
| 899 video_sender_config_.aes_key = | |
| 900 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef"); | |
| 901 | |
| 902 video_receiver_config_.aes_iv_mask = video_sender_config_.aes_iv_mask; | |
| 903 video_receiver_config_.aes_key = video_sender_config_.aes_key; | |
| 904 | |
| 905 Create(); | |
| 906 | |
| 907 int frames_counter = 0; | |
| 908 for (; frames_counter < 20; ++frames_counter) { | |
| 909 const base::TimeTicks send_time = testing_clock_.NowTicks(); | |
| 910 | |
| 911 SendVideoFrame(frames_counter, send_time); | |
| 912 | |
| 913 test_receiver_video_callback_->AddExpectedResult(frames_counter, | |
| 914 video_sender_config_.width, video_sender_config_.height, send_time); | |
| 915 | |
| 916 // GetRawVideoFrame will not return the frame until we are close to the | |
| 917 // time in which we should render the frame. | |
| 918 frame_receiver_->GetRawVideoFrame( | |
| 919 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | |
| 920 test_receiver_video_callback_)); | |
| 921 RunTasks(kFrameTimerMs); | |
| 922 } | |
| 923 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | |
| 924 EXPECT_EQ(frames_counter, | |
| 925 test_receiver_video_callback_->number_times_called()); | |
| 926 } | |
| 927 | |
| 928 | |
| 929 TEST_F(End2EndTest, CryptoAudio) { | |
| 930 SetupConfig(kPcm16, 32000, false, 1); | |
| 931 | |
| 932 audio_sender_config_.aes_iv_mask = | |
| 933 ConvertFromBase16String("abcdeffedcba12345678900987654321"); | |
| 934 audio_sender_config_.aes_key = | |
| 935 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0"); | |
| 936 | |
| 937 audio_receiver_config_.aes_iv_mask = audio_sender_config_.aes_iv_mask; | |
| 938 audio_receiver_config_.aes_key = audio_sender_config_.aes_key; | |
| 939 | |
| 940 Create(); | |
| 941 test_receiver_audio_callback_->SetExpectedResult(32000, 18, 20); | |
| 942 | |
| 943 int frames_counter = 0; | |
| 944 for (; frames_counter < 20; ++frames_counter) { | |
| 945 int num_10ms_blocks = 2; | |
| 946 | |
| 947 const base::TimeTicks send_time = testing_clock_.NowTicks(); | |
| 948 | |
| 949 PcmAudioFrame* audio_frame = CreateAudioFrame(num_10ms_blocks, | |
| 950 kSoundFrequency, 32000); | |
| 951 | |
| 952 if (frames_counter != 0) { | |
| 953 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 954 // first samples will be 0 and then slowly ramp up to its real amplitude; | |
| 955 // ignore the first frame. | |
| 956 test_receiver_audio_callback_->AddExpectedResult(audio_frame, | |
| 957 num_10ms_blocks, send_time); | |
| 958 } | |
| 959 frame_input_->InsertRawAudioFrame(audio_frame, send_time, | |
| 960 base::Bind(FrameInput::DeleteAudioFrame, audio_frame)); | |
| 961 | |
| 962 RunTasks(num_10ms_blocks * 10); | |
| 963 | |
| 964 if (frames_counter == 0) { | |
| 965 frame_receiver_->GetRawAudioFrame(num_10ms_blocks, | |
| 966 32000, | |
| 967 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 968 test_receiver_audio_callback_)); | |
| 969 } else { | |
| 970 frame_receiver_->GetRawAudioFrame(num_10ms_blocks, | |
| 971 32000, | |
| 972 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 973 test_receiver_audio_callback_)); | |
| 974 } | |
| 975 } | |
| 976 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | |
| 977 EXPECT_EQ(frames_counter - 1, | |
| 978 test_receiver_audio_callback_->number_times_called()); | |
| 979 } | |
| 980 | |
| 981 | |
| 982 | |
| 865 // TODO(pwestin): Add repeatable packet loss test. | 983 // TODO(pwestin): Add repeatable packet loss test. |
| 866 // TODO(pwestin): Add test for misaligned send get calls. | 984 // TODO(pwestin): Add test for misaligned send get calls. |
| 867 // TODO(pwestin): Add more tests that does not resample. | 985 // TODO(pwestin): Add more tests that does not resample. |
| 868 // TODO(pwestin): Add test when we have starvation for our RunTask. | 986 // TODO(pwestin): Add test when we have starvation for our RunTask. |
| 869 | 987 |
| 870 } // namespace cast | 988 } // namespace cast |
| 871 } // namespace media | 989 } // namespace media |
| OLD | NEW |