OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2008 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 23 matching lines...) Expand all Loading... |
34 | 34 |
35 namespace { | 35 namespace { |
36 | 36 |
37 const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1); | 37 const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1); |
38 const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1); | 38 const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1); |
39 const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2); | 39 const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2); |
40 const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1); | 40 const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1); |
41 const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1); | 41 const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1); |
42 const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1); | 42 const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1); |
43 const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1); | 43 const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1); |
44 const cricket::AudioCodec kTelephoneEventCodec(106, | 44 const cricket::AudioCodec |
45 "telephone-event", | 45 kTelephoneEventCodec1(106, "telephone-event", 8000, 0, 1); |
46 8000, | 46 const cricket::AudioCodec |
47 0, | 47 kTelephoneEventCodec2(107, "telephone-event", 32000, 0, 1); |
48 1); | 48 |
49 const uint32_t kSsrc1 = 0x99; | 49 const uint32_t kSsrc1 = 0x99; |
50 const uint32_t kSsrc2 = 2; | 50 const uint32_t kSsrc2 = 2; |
51 const uint32_t kSsrc3 = 3; | 51 const uint32_t kSsrc3 = 3; |
52 const uint32_t kSsrcs4[] = { 1, 2, 3, 4 }; | 52 const uint32_t kSsrcs4[] = { 1, 2, 3, 4 }; |
53 | 53 |
54 constexpr int kRtpHistoryMs = 5000; | 54 constexpr int kRtpHistoryMs = 5000; |
55 | 55 |
56 class FakeVoEWrapper : public cricket::VoEWrapper { | 56 class FakeVoEWrapper : public cricket::VoEWrapper { |
57 public: | 57 public: |
58 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine) | 58 explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine) |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 // send stream. | 196 // send stream. |
197 EXPECT_TRUE(channel_->AddSendStream( | 197 EXPECT_TRUE(channel_->AddSendStream( |
198 cricket::StreamParams::CreateLegacy(kSsrc1))); | 198 cricket::StreamParams::CreateLegacy(kSsrc1))); |
199 } | 199 } |
200 | 200 |
201 // Test we can only InsertDtmf when the other side supports telephone-event. | 201 // Test we can only InsertDtmf when the other side supports telephone-event. |
202 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); | 202 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); |
203 SetSend(channel_, true); | 203 SetSend(channel_, true); |
204 EXPECT_FALSE(channel_->CanInsertDtmf()); | 204 EXPECT_FALSE(channel_->CanInsertDtmf()); |
205 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111)); | 205 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111)); |
206 send_parameters_.codecs.push_back(kTelephoneEventCodec); | 206 send_parameters_.codecs.push_back(kTelephoneEventCodec1); |
207 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); | 207 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); |
208 EXPECT_TRUE(channel_->CanInsertDtmf()); | 208 EXPECT_TRUE(channel_->CanInsertDtmf()); |
209 | 209 |
210 if (!caller) { | 210 if (!caller) { |
211 // If this is callee, there's no active send channel yet. | 211 // If this is callee, there's no active send channel yet. |
212 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123)); | 212 EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123)); |
213 EXPECT_TRUE(channel_->AddSendStream( | 213 EXPECT_TRUE(channel_->AddSendStream( |
214 cricket::StreamParams::CreateLegacy(kSsrc1))); | 214 cricket::StreamParams::CreateLegacy(kSsrc1))); |
215 } | 215 } |
216 | 216 |
217 // Check we fail if the ssrc is invalid. | 217 // Check we fail if the ssrc is invalid. |
218 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111)); | 218 EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111)); |
219 | 219 |
220 // Test send. | 220 // Test send. |
221 cricket::FakeAudioSendStream::TelephoneEvent telephone_event = | 221 cricket::FakeAudioSendStream::TelephoneEvent telephone_event = |
222 GetSendStream(kSsrc1).GetLatestTelephoneEvent(); | 222 GetSendStream(kSsrc1).GetLatestTelephoneEvent(); |
223 EXPECT_EQ(-1, telephone_event.payload_type); | 223 EXPECT_EQ(-1, telephone_event.payload_type); |
224 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123)); | 224 EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123)); |
225 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent(); | 225 telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent(); |
226 EXPECT_EQ(kTelephoneEventCodec.id, telephone_event.payload_type); | 226 EXPECT_EQ(kTelephoneEventCodec1.id, telephone_event.payload_type); |
227 EXPECT_EQ(2, telephone_event.event_code); | 227 EXPECT_EQ(2, telephone_event.event_code); |
228 EXPECT_EQ(123, telephone_event.duration_ms); | 228 EXPECT_EQ(123, telephone_event.duration_ms); |
229 } | 229 } |
230 | 230 |
231 // Test that send bandwidth is set correctly. | 231 // Test that send bandwidth is set correctly. |
232 // |codec| is the codec under test. | 232 // |codec| is the codec under test. |
233 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth(). | 233 // |max_bitrate| is a parameter to set to SetMaxSendBandwidth(). |
234 // |expected_result| is the expected result from SetMaxSendBandwidth(). | 234 // |expected_result| is the expected result from SetMaxSendBandwidth(). |
235 // |expected_bitrate| is the expected audio bitrate afterward. | 235 // |expected_bitrate| is the expected audio bitrate afterward. |
236 void TestMaxSendBandwidth(const cricket::AudioCodec& codec, | 236 void TestMaxSendBandwidth(const cricket::AudioCodec& codec, |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 // Tests that we can find codecs by name or id, and that we interpret the | 568 // Tests that we can find codecs by name or id, and that we interpret the |
569 // clockrate and bitrate fields properly. | 569 // clockrate and bitrate fields properly. |
570 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) { | 570 TEST_F(WebRtcVoiceEngineTestFake, FindCodec) { |
571 cricket::AudioCodec codec; | 571 cricket::AudioCodec codec; |
572 webrtc::CodecInst codec_inst; | 572 webrtc::CodecInst codec_inst; |
573 // Find PCMU with explicit clockrate and bitrate. | 573 // Find PCMU with explicit clockrate and bitrate. |
574 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst)); | 574 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst)); |
575 // Find ISAC with explicit clockrate and 0 bitrate. | 575 // Find ISAC with explicit clockrate and 0 bitrate. |
576 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst)); | 576 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst)); |
577 // Find telephone-event with explicit clockrate and 0 bitrate. | 577 // Find telephone-event with explicit clockrate and 0 bitrate. |
578 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec, | 578 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec1, |
| 579 &codec_inst)); |
| 580 // Find telephone-event with explicit clockrate and 0 bitrate. |
| 581 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec2, |
579 &codec_inst)); | 582 &codec_inst)); |
580 // Find ISAC with a different payload id. | 583 // Find ISAC with a different payload id. |
581 codec = kIsacCodec; | 584 codec = kIsacCodec; |
582 codec.id = 127; | 585 codec.id = 127; |
583 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst)); | 586 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst)); |
584 EXPECT_EQ(codec.id, codec_inst.pltype); | 587 EXPECT_EQ(codec.id, codec_inst.pltype); |
585 // Find PCMU with a 0 clockrate. | 588 // Find PCMU with a 0 clockrate. |
586 codec = kPcmuCodec; | 589 codec = kPcmuCodec; |
587 codec.clockrate = 0; | 590 codec.clockrate = 0; |
588 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst)); | 591 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst)); |
(...skipping 12 matching lines...) Expand all Loading... |
601 EXPECT_EQ(codec.id, codec_inst.pltype); | 604 EXPECT_EQ(codec.id, codec_inst.pltype); |
602 EXPECT_EQ(32000, codec_inst.rate); | 605 EXPECT_EQ(32000, codec_inst.rate); |
603 } | 606 } |
604 | 607 |
605 // Test that we set our inbound codecs properly, including changing PT. | 608 // Test that we set our inbound codecs properly, including changing PT. |
606 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) { | 609 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) { |
607 EXPECT_TRUE(SetupChannel()); | 610 EXPECT_TRUE(SetupChannel()); |
608 cricket::AudioRecvParameters parameters; | 611 cricket::AudioRecvParameters parameters; |
609 parameters.codecs.push_back(kIsacCodec); | 612 parameters.codecs.push_back(kIsacCodec); |
610 parameters.codecs.push_back(kPcmuCodec); | 613 parameters.codecs.push_back(kPcmuCodec); |
611 parameters.codecs.push_back(kTelephoneEventCodec); | 614 parameters.codecs.push_back(kTelephoneEventCodec1); |
612 parameters.codecs[0].id = 106; // collide with existing telephone-event | 615 parameters.codecs.push_back(kTelephoneEventCodec2); |
| 616 parameters.codecs[0].id = 106; // collide with existing CN 32k |
613 parameters.codecs[2].id = 126; | 617 parameters.codecs[2].id = 126; |
614 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); | 618 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); |
615 EXPECT_TRUE(AddRecvStream(kSsrc1)); | 619 EXPECT_TRUE(AddRecvStream(kSsrc1)); |
616 int channel_num = voe_.GetLastChannel(); | 620 int channel_num = voe_.GetLastChannel(); |
| 621 |
617 webrtc::CodecInst gcodec; | 622 webrtc::CodecInst gcodec; |
618 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC"); | 623 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC"); |
619 gcodec.plfreq = 16000; | 624 gcodec.plfreq = 16000; |
620 gcodec.channels = 1; | 625 gcodec.channels = 1; |
621 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec)); | 626 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec)); |
622 EXPECT_EQ(106, gcodec.pltype); | 627 EXPECT_EQ(106, gcodec.pltype); |
623 EXPECT_STREQ("ISAC", gcodec.plname); | 628 EXPECT_STREQ("ISAC", gcodec.plname); |
| 629 |
624 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event"); | 630 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event"); |
625 gcodec.plfreq = 8000; | 631 gcodec.plfreq = 8000; |
626 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec)); | 632 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec)); |
627 EXPECT_EQ(126, gcodec.pltype); | 633 EXPECT_EQ(126, gcodec.pltype); |
628 EXPECT_STREQ("telephone-event", gcodec.plname); | 634 EXPECT_STREQ("telephone-event", gcodec.plname); |
| 635 |
| 636 gcodec.plfreq = 32000; |
| 637 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec)); |
| 638 EXPECT_EQ(107, gcodec.pltype); |
| 639 EXPECT_STREQ("telephone-event", gcodec.plname); |
629 } | 640 } |
630 | 641 |
631 // Test that we fail to set an unknown inbound codec. | 642 // Test that we fail to set an unknown inbound codec. |
632 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) { | 643 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) { |
633 EXPECT_TRUE(SetupChannel()); | 644 EXPECT_TRUE(SetupChannel()); |
634 cricket::AudioRecvParameters parameters; | 645 cricket::AudioRecvParameters parameters; |
635 parameters.codecs.push_back(kIsacCodec); | 646 parameters.codecs.push_back(kIsacCodec); |
636 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1)); | 647 parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1)); |
637 EXPECT_FALSE(channel_->SetRecvParameters(parameters)); | 648 EXPECT_FALSE(channel_->SetRecvParameters(parameters)); |
638 } | 649 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus)); | 721 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus)); |
711 EXPECT_EQ(111, opus.pltype); | 722 EXPECT_EQ(111, opus.pltype); |
712 } | 723 } |
713 | 724 |
714 // Test that changes to recv codecs are applied to all streams. | 725 // Test that changes to recv codecs are applied to all streams. |
715 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) { | 726 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) { |
716 EXPECT_TRUE(SetupChannel()); | 727 EXPECT_TRUE(SetupChannel()); |
717 cricket::AudioRecvParameters parameters; | 728 cricket::AudioRecvParameters parameters; |
718 parameters.codecs.push_back(kIsacCodec); | 729 parameters.codecs.push_back(kIsacCodec); |
719 parameters.codecs.push_back(kPcmuCodec); | 730 parameters.codecs.push_back(kPcmuCodec); |
720 parameters.codecs.push_back(kTelephoneEventCodec); | 731 parameters.codecs.push_back(kTelephoneEventCodec1); |
721 parameters.codecs[0].id = 106; // collide with existing telephone-event | 732 parameters.codecs.push_back(kTelephoneEventCodec2); |
| 733 parameters.codecs[0].id = 106; // collide with existing CN 32k |
722 parameters.codecs[2].id = 126; | 734 parameters.codecs[2].id = 126; |
723 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); | 735 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); |
724 EXPECT_TRUE(AddRecvStream(kSsrc1)); | 736 EXPECT_TRUE(AddRecvStream(kSsrc1)); |
725 int channel_num2 = voe_.GetLastChannel(); | 737 int channel_num2 = voe_.GetLastChannel(); |
| 738 |
726 webrtc::CodecInst gcodec; | 739 webrtc::CodecInst gcodec; |
727 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC"); | 740 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC"); |
728 gcodec.plfreq = 16000; | 741 gcodec.plfreq = 16000; |
729 gcodec.channels = 1; | 742 gcodec.channels = 1; |
730 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); | 743 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); |
731 EXPECT_EQ(106, gcodec.pltype); | 744 EXPECT_EQ(106, gcodec.pltype); |
732 EXPECT_STREQ("ISAC", gcodec.plname); | 745 EXPECT_STREQ("ISAC", gcodec.plname); |
| 746 |
733 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event"); | 747 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event"); |
734 gcodec.plfreq = 8000; | 748 gcodec.plfreq = 8000; |
735 gcodec.channels = 1; | 749 gcodec.channels = 1; |
736 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); | 750 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); |
737 EXPECT_EQ(126, gcodec.pltype); | 751 EXPECT_EQ(126, gcodec.pltype); |
738 EXPECT_STREQ("telephone-event", gcodec.plname); | 752 EXPECT_STREQ("telephone-event", gcodec.plname); |
| 753 |
| 754 gcodec.plfreq = 32000; |
| 755 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); |
| 756 EXPECT_EQ(107, gcodec.pltype); |
| 757 EXPECT_STREQ("telephone-event", gcodec.plname); |
739 } | 758 } |
740 | 759 |
741 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) { | 760 TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) { |
742 EXPECT_TRUE(SetupRecvStream()); | 761 EXPECT_TRUE(SetupRecvStream()); |
743 cricket::AudioRecvParameters parameters; | 762 cricket::AudioRecvParameters parameters; |
744 parameters.codecs.push_back(kIsacCodec); | 763 parameters.codecs.push_back(kIsacCodec); |
745 parameters.codecs[0].id = 106; // collide with existing telephone-event | 764 parameters.codecs[0].id = 106; // collide with existing CN 32k |
746 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); | 765 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); |
747 | 766 |
748 int channel_num2 = voe_.GetLastChannel(); | 767 int channel_num2 = voe_.GetLastChannel(); |
749 webrtc::CodecInst gcodec; | 768 webrtc::CodecInst gcodec; |
750 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC"); | 769 rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC"); |
751 gcodec.plfreq = 16000; | 770 gcodec.plfreq = 16000; |
752 gcodec.channels = 1; | 771 gcodec.channels = 1; |
753 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); | 772 EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec)); |
754 EXPECT_EQ(106, gcodec.pltype); | 773 EXPECT_EQ(106, gcodec.pltype); |
755 EXPECT_STREQ("ISAC", gcodec.plname); | 774 EXPECT_STREQ("ISAC", gcodec.plname); |
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1906 cricket::AudioSendParameters parameters; | 1925 cricket::AudioSendParameters parameters; |
1907 EXPECT_FALSE(channel_->SetSendParameters(parameters)); | 1926 EXPECT_FALSE(channel_->SetSendParameters(parameters)); |
1908 } | 1927 } |
1909 | 1928 |
1910 // Test that we can set send codecs even with telephone-event codec as the first | 1929 // Test that we can set send codecs even with telephone-event codec as the first |
1911 // one on the list. | 1930 // one on the list. |
1912 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) { | 1931 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) { |
1913 EXPECT_TRUE(SetupSendStream()); | 1932 EXPECT_TRUE(SetupSendStream()); |
1914 int channel_num = voe_.GetLastChannel(); | 1933 int channel_num = voe_.GetLastChannel(); |
1915 cricket::AudioSendParameters parameters; | 1934 cricket::AudioSendParameters parameters; |
1916 parameters.codecs.push_back(kTelephoneEventCodec); | 1935 parameters.codecs.push_back(kTelephoneEventCodec1); |
1917 parameters.codecs.push_back(kIsacCodec); | 1936 parameters.codecs.push_back(kIsacCodec); |
1918 parameters.codecs.push_back(kPcmuCodec); | 1937 parameters.codecs.push_back(kPcmuCodec); |
1919 parameters.codecs[0].id = 98; // DTMF | 1938 parameters.codecs[0].id = 98; // DTMF |
1920 parameters.codecs[1].id = 96; | 1939 parameters.codecs[1].id = 96; |
1921 EXPECT_TRUE(channel_->SetSendParameters(parameters)); | 1940 EXPECT_TRUE(channel_->SetSendParameters(parameters)); |
1922 webrtc::CodecInst gcodec; | 1941 webrtc::CodecInst gcodec; |
1923 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); | 1942 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); |
1924 EXPECT_EQ(96, gcodec.pltype); | 1943 EXPECT_EQ(96, gcodec.pltype); |
1925 EXPECT_STREQ("ISAC", gcodec.plname); | 1944 EXPECT_STREQ("ISAC", gcodec.plname); |
1926 EXPECT_TRUE(channel_->CanInsertDtmf()); | 1945 EXPECT_TRUE(channel_->CanInsertDtmf()); |
1927 } | 1946 } |
1928 | 1947 |
1929 // Test that payload type range is limited for telephone-event codec. | 1948 // Test that payload type range is limited for telephone-event codec. |
1930 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) { | 1949 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFPayloadTypeOutOfRange) { |
1931 EXPECT_TRUE(SetupSendStream()); | 1950 EXPECT_TRUE(SetupSendStream()); |
1932 cricket::AudioSendParameters parameters; | 1951 cricket::AudioSendParameters parameters; |
1933 parameters.codecs.push_back(kTelephoneEventCodec); | 1952 parameters.codecs.push_back(kTelephoneEventCodec1); |
1934 parameters.codecs.push_back(kIsacCodec); | 1953 parameters.codecs.push_back(kIsacCodec); |
1935 parameters.codecs[0].id = 0; // DTMF | 1954 parameters.codecs[0].id = 0; // DTMF |
1936 parameters.codecs[1].id = 96; | 1955 parameters.codecs[1].id = 96; |
1937 EXPECT_TRUE(channel_->SetSendParameters(parameters)); | 1956 EXPECT_TRUE(channel_->SetSendParameters(parameters)); |
1938 EXPECT_TRUE(channel_->CanInsertDtmf()); | 1957 EXPECT_TRUE(channel_->CanInsertDtmf()); |
1939 parameters.codecs[0].id = 128; // DTMF | 1958 parameters.codecs[0].id = 128; // DTMF |
1940 EXPECT_FALSE(channel_->SetSendParameters(parameters)); | 1959 EXPECT_FALSE(channel_->SetSendParameters(parameters)); |
1941 EXPECT_FALSE(channel_->CanInsertDtmf()); | 1960 EXPECT_FALSE(channel_->CanInsertDtmf()); |
1942 parameters.codecs[0].id = 127; | 1961 parameters.codecs[0].id = 127; |
1943 EXPECT_TRUE(channel_->SetSendParameters(parameters)); | 1962 EXPECT_TRUE(channel_->SetSendParameters(parameters)); |
(...skipping 25 matching lines...) Expand all Loading... |
1969 // Test that we set VAD and DTMF types correctly as caller. | 1988 // Test that we set VAD and DTMF types correctly as caller. |
1970 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) { | 1989 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) { |
1971 EXPECT_TRUE(SetupSendStream()); | 1990 EXPECT_TRUE(SetupSendStream()); |
1972 int channel_num = voe_.GetLastChannel(); | 1991 int channel_num = voe_.GetLastChannel(); |
1973 cricket::AudioSendParameters parameters; | 1992 cricket::AudioSendParameters parameters; |
1974 parameters.codecs.push_back(kIsacCodec); | 1993 parameters.codecs.push_back(kIsacCodec); |
1975 parameters.codecs.push_back(kPcmuCodec); | 1994 parameters.codecs.push_back(kPcmuCodec); |
1976 // TODO(juberti): cn 32000 | 1995 // TODO(juberti): cn 32000 |
1977 parameters.codecs.push_back(kCn16000Codec); | 1996 parameters.codecs.push_back(kCn16000Codec); |
1978 parameters.codecs.push_back(kCn8000Codec); | 1997 parameters.codecs.push_back(kCn8000Codec); |
1979 parameters.codecs.push_back(kTelephoneEventCodec); | 1998 parameters.codecs.push_back(kTelephoneEventCodec1); |
1980 parameters.codecs[0].id = 96; | 1999 parameters.codecs[0].id = 96; |
1981 parameters.codecs[2].id = 97; // wideband CN | 2000 parameters.codecs[2].id = 97; // wideband CN |
1982 parameters.codecs[4].id = 98; // DTMF | 2001 parameters.codecs[4].id = 98; // DTMF |
1983 EXPECT_TRUE(channel_->SetSendParameters(parameters)); | 2002 EXPECT_TRUE(channel_->SetSendParameters(parameters)); |
1984 webrtc::CodecInst gcodec; | 2003 webrtc::CodecInst gcodec; |
1985 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); | 2004 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); |
1986 EXPECT_EQ(96, gcodec.pltype); | 2005 EXPECT_EQ(96, gcodec.pltype); |
1987 EXPECT_STREQ("ISAC", gcodec.plname); | 2006 EXPECT_STREQ("ISAC", gcodec.plname); |
1988 EXPECT_TRUE(voe_.GetVAD(channel_num)); | 2007 EXPECT_TRUE(voe_.GetVAD(channel_num)); |
1989 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false)); | 2008 EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false)); |
1990 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true)); | 2009 EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true)); |
1991 EXPECT_TRUE(channel_->CanInsertDtmf()); | 2010 EXPECT_TRUE(channel_->CanInsertDtmf()); |
1992 } | 2011 } |
1993 | 2012 |
1994 // Test that we set VAD and DTMF types correctly as callee. | 2013 // Test that we set VAD and DTMF types correctly as callee. |
1995 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) { | 2014 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) { |
1996 EXPECT_TRUE(SetupChannel()); | 2015 EXPECT_TRUE(SetupChannel()); |
1997 cricket::AudioSendParameters parameters; | 2016 cricket::AudioSendParameters parameters; |
1998 parameters.codecs.push_back(kIsacCodec); | 2017 parameters.codecs.push_back(kIsacCodec); |
1999 parameters.codecs.push_back(kPcmuCodec); | 2018 parameters.codecs.push_back(kPcmuCodec); |
2000 // TODO(juberti): cn 32000 | 2019 // TODO(juberti): cn 32000 |
2001 parameters.codecs.push_back(kCn16000Codec); | 2020 parameters.codecs.push_back(kCn16000Codec); |
2002 parameters.codecs.push_back(kCn8000Codec); | 2021 parameters.codecs.push_back(kCn8000Codec); |
2003 parameters.codecs.push_back(kTelephoneEventCodec); | 2022 parameters.codecs.push_back(kTelephoneEventCodec1); |
2004 parameters.codecs[0].id = 96; | 2023 parameters.codecs[0].id = 96; |
2005 parameters.codecs[2].id = 97; // wideband CN | 2024 parameters.codecs[2].id = 97; // wideband CN |
2006 parameters.codecs[4].id = 98; // DTMF | 2025 parameters.codecs[4].id = 98; // DTMF |
2007 EXPECT_TRUE(channel_->SetSendParameters(parameters)); | 2026 EXPECT_TRUE(channel_->SetSendParameters(parameters)); |
2008 EXPECT_TRUE(channel_->AddSendStream( | 2027 EXPECT_TRUE(channel_->AddSendStream( |
2009 cricket::StreamParams::CreateLegacy(kSsrc1))); | 2028 cricket::StreamParams::CreateLegacy(kSsrc1))); |
2010 int channel_num = voe_.GetLastChannel(); | 2029 int channel_num = voe_.GetLastChannel(); |
2011 | 2030 |
2012 webrtc::CodecInst gcodec; | 2031 webrtc::CodecInst gcodec; |
2013 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); | 2032 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2058 | 2077 |
2059 // Test that we perform case-insensitive matching of codec names. | 2078 // Test that we perform case-insensitive matching of codec names. |
2060 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) { | 2079 TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) { |
2061 EXPECT_TRUE(SetupSendStream()); | 2080 EXPECT_TRUE(SetupSendStream()); |
2062 int channel_num = voe_.GetLastChannel(); | 2081 int channel_num = voe_.GetLastChannel(); |
2063 cricket::AudioSendParameters parameters; | 2082 cricket::AudioSendParameters parameters; |
2064 parameters.codecs.push_back(kIsacCodec); | 2083 parameters.codecs.push_back(kIsacCodec); |
2065 parameters.codecs.push_back(kPcmuCodec); | 2084 parameters.codecs.push_back(kPcmuCodec); |
2066 parameters.codecs.push_back(kCn16000Codec); | 2085 parameters.codecs.push_back(kCn16000Codec); |
2067 parameters.codecs.push_back(kCn8000Codec); | 2086 parameters.codecs.push_back(kCn8000Codec); |
2068 parameters.codecs.push_back(kTelephoneEventCodec); | 2087 parameters.codecs.push_back(kTelephoneEventCodec1); |
2069 parameters.codecs[0].name = "iSaC"; | 2088 parameters.codecs[0].name = "iSaC"; |
2070 parameters.codecs[0].id = 96; | 2089 parameters.codecs[0].id = 96; |
2071 parameters.codecs[2].id = 97; // wideband CN | 2090 parameters.codecs[2].id = 97; // wideband CN |
2072 parameters.codecs[4].id = 98; // DTMF | 2091 parameters.codecs[4].id = 98; // DTMF |
2073 EXPECT_TRUE(channel_->SetSendParameters(parameters)); | 2092 EXPECT_TRUE(channel_->SetSendParameters(parameters)); |
2074 webrtc::CodecInst gcodec; | 2093 webrtc::CodecInst gcodec; |
2075 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); | 2094 EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec)); |
2076 EXPECT_EQ(96, gcodec.pltype); | 2095 EXPECT_EQ(96, gcodec.pltype); |
2077 EXPECT_STREQ("ISAC", gcodec.plname); | 2096 EXPECT_STREQ("ISAC", gcodec.plname); |
2078 EXPECT_TRUE(voe_.GetVAD(channel_num)); | 2097 EXPECT_TRUE(voe_.GetVAD(channel_num)); |
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3416 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3435 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3417 cricket::AudioCodec(96, "G722", 8000, 0, 1), nullptr)); | 3436 cricket::AudioCodec(96, "G722", 8000, 0, 1), nullptr)); |
3418 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3437 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3419 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr)); | 3438 cricket::AudioCodec(96, "CN", 32000, 0, 1), nullptr)); |
3420 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3439 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3421 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr)); | 3440 cricket::AudioCodec(96, "CN", 16000, 0, 1), nullptr)); |
3422 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3441 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3423 cricket::AudioCodec(96, "CN", 8000, 0, 1), nullptr)); | 3442 cricket::AudioCodec(96, "CN", 8000, 0, 1), nullptr)); |
3424 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3443 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3425 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr)); | 3444 cricket::AudioCodec(96, "telephone-event", 8000, 0, 1), nullptr)); |
| 3445 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
| 3446 cricket::AudioCodec(96, "telephone-event", 16000, 0, 1), nullptr)); |
| 3447 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
| 3448 cricket::AudioCodec(96, "telephone-event", 32000, 0, 1), nullptr)); |
| 3449 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
| 3450 cricket::AudioCodec(96, "telephone-event", 48000, 0, 1), nullptr)); |
3426 // Check codecs with an id by id. | 3451 // Check codecs with an id by id. |
3427 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3452 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3428 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU | 3453 cricket::AudioCodec(0, "", 8000, 0, 1), nullptr)); // PCMU |
3429 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3454 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3430 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA | 3455 cricket::AudioCodec(8, "", 8000, 0, 1), nullptr)); // PCMA |
3431 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3456 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3432 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722 | 3457 cricket::AudioCodec(9, "", 8000, 0, 1), nullptr)); // G722 |
3433 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3458 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3434 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN | 3459 cricket::AudioCodec(13, "", 8000, 0, 1), nullptr)); // CN |
3435 // Check sample/bitrate matching. | 3460 // Check sample/bitrate matching. |
3436 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3461 EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3437 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr)); | 3462 cricket::AudioCodec(0, "PCMU", 8000, 64000, 1), nullptr)); |
3438 // Check that bad codecs fail. | 3463 // Check that bad codecs fail. |
3439 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3464 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3440 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr)); | 3465 cricket::AudioCodec(99, "ABCD", 0, 0, 1), nullptr)); |
3441 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3466 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3442 cricket::AudioCodec(88, "", 0, 0, 1), nullptr)); | 3467 cricket::AudioCodec(88, "", 0, 0, 1), nullptr)); |
3443 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3468 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3444 cricket::AudioCodec(0, "", 0, 0, 2), nullptr)); | 3469 cricket::AudioCodec(0, "", 0, 0, 2), nullptr)); |
3445 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3470 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3446 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr)); | 3471 cricket::AudioCodec(0, "", 5000, 0, 1), nullptr)); |
3447 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( | 3472 EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst( |
3448 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr)); | 3473 cricket::AudioCodec(0, "", 0, 5000, 1), nullptr)); |
3449 | 3474 |
3450 // Verify the payload id of common audio codecs, including CN, ISAC, and G722. | 3475 // Verify the payload id of common audio codecs, including CN, ISAC, and G722. |
3451 // TODO(ossu): Why are the payload types of codecs with non-static payload | 3476 // TODO(ossu): Why are the payload types of codecs with non-static payload |
3452 // type assignments checked here? It shouldn't really matter. | 3477 // type assignments checked here? It shouldn't really matter. |
3453 cricket::WebRtcVoiceEngine engine( | 3478 cricket::WebRtcVoiceEngine engine( |
3454 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory()); | 3479 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory()); |
3455 for (std::vector<cricket::AudioCodec>::const_iterator it = | 3480 for (const cricket::AudioCodec& codec : engine.send_codecs()) { |
3456 engine.send_codecs().begin(); | 3481 if (codec.name == "CN" && codec.clockrate == 16000) { |
3457 it != engine.send_codecs().end(); ++it) { | 3482 EXPECT_EQ(105, codec.id); |
3458 if (it->name == "CN" && it->clockrate == 16000) { | 3483 } else if (codec.name == "CN" && codec.clockrate == 32000) { |
3459 EXPECT_EQ(105, it->id); | 3484 EXPECT_EQ(106, codec.id); |
3460 } else if (it->name == "CN" && it->clockrate == 32000) { | 3485 } else if (codec.name == "ISAC" && codec.clockrate == 16000) { |
3461 EXPECT_EQ(106, it->id); | 3486 EXPECT_EQ(103, codec.id); |
3462 } else if (it->name == "ISAC" && it->clockrate == 16000) { | 3487 } else if (codec.name == "ISAC" && codec.clockrate == 32000) { |
3463 EXPECT_EQ(103, it->id); | 3488 EXPECT_EQ(104, codec.id); |
3464 } else if (it->name == "ISAC" && it->clockrate == 32000) { | 3489 } else if (codec.name == "G722" && codec.clockrate == 8000) { |
3465 EXPECT_EQ(104, it->id); | 3490 EXPECT_EQ(9, codec.id); |
3466 } else if (it->name == "G722" && it->clockrate == 8000) { | 3491 } else if (codec.name == "telephone-event" && codec.clockrate == 8000) { |
3467 EXPECT_EQ(9, it->id); | 3492 EXPECT_EQ(126, codec.id); |
3468 } else if (it->name == "telephone-event") { | 3493 // TODO(solenberg): 16k, 32k, 48k DTMF should be dynamically assigned. |
3469 EXPECT_EQ(126, it->id); | 3494 // Remove these checks once both send and receive side assigns payload types |
3470 } else if (it->name == "opus") { | 3495 // dynamically. |
3471 EXPECT_EQ(111, it->id); | 3496 } else if (codec.name == "telephone-event" && codec.clockrate == 16000) { |
3472 ASSERT_TRUE(it->params.find("minptime") != it->params.end()); | 3497 EXPECT_EQ(113, codec.id); |
3473 EXPECT_EQ("10", it->params.find("minptime")->second); | 3498 } else if (codec.name == "telephone-event" && codec.clockrate == 32000) { |
3474 ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end()); | 3499 EXPECT_EQ(112, codec.id); |
3475 EXPECT_EQ("1", it->params.find("useinbandfec")->second); | 3500 } else if (codec.name == "telephone-event" && codec.clockrate == 48000) { |
| 3501 EXPECT_EQ(110, codec.id); |
| 3502 } else if (codec.name == "opus") { |
| 3503 EXPECT_EQ(111, codec.id); |
| 3504 ASSERT_TRUE(codec.params.find("minptime") != codec.params.end()); |
| 3505 EXPECT_EQ("10", codec.params.find("minptime")->second); |
| 3506 ASSERT_TRUE(codec.params.find("useinbandfec") != codec.params.end()); |
| 3507 EXPECT_EQ("1", codec.params.find("useinbandfec")->second); |
3476 } | 3508 } |
3477 } | 3509 } |
3478 } | 3510 } |
3479 | 3511 |
3480 // Tests that VoE supports at least 32 channels | 3512 // Tests that VoE supports at least 32 channels |
3481 TEST(WebRtcVoiceEngineTest, Has32Channels) { | 3513 TEST(WebRtcVoiceEngineTest, Has32Channels) { |
3482 cricket::WebRtcVoiceEngine engine( | 3514 cricket::WebRtcVoiceEngine engine( |
3483 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory()); | 3515 nullptr, webrtc::MockAudioDecoderFactory::CreateUnusedFactory()); |
3484 webrtc::RtcEventLogNullImpl event_log; | 3516 webrtc::RtcEventLogNullImpl event_log; |
3485 std::unique_ptr<webrtc::Call> call( | 3517 std::unique_ptr<webrtc::Call> call( |
(...skipping 30 matching lines...) Expand all Loading... |
3516 nullptr, webrtc::CreateBuiltinAudioDecoderFactory()); | 3548 nullptr, webrtc::CreateBuiltinAudioDecoderFactory()); |
3517 webrtc::RtcEventLogNullImpl event_log; | 3549 webrtc::RtcEventLogNullImpl event_log; |
3518 std::unique_ptr<webrtc::Call> call( | 3550 std::unique_ptr<webrtc::Call> call( |
3519 webrtc::Call::Create(webrtc::Call::Config(&event_log))); | 3551 webrtc::Call::Create(webrtc::Call::Config(&event_log))); |
3520 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(), | 3552 cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(), |
3521 cricket::AudioOptions(), call.get()); | 3553 cricket::AudioOptions(), call.get()); |
3522 cricket::AudioRecvParameters parameters; | 3554 cricket::AudioRecvParameters parameters; |
3523 parameters.codecs = engine.recv_codecs(); | 3555 parameters.codecs = engine.recv_codecs(); |
3524 EXPECT_TRUE(channel.SetRecvParameters(parameters)); | 3556 EXPECT_TRUE(channel.SetRecvParameters(parameters)); |
3525 } | 3557 } |
OLD | NEW |