Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 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 21 matching lines...) Expand all Loading... | |
| 32 #else | 32 #else |
| 33 #define ASSERT_CRYPTO(cd, s, cs) \ | 33 #define ASSERT_CRYPTO(cd, s, cs) \ |
| 34 ASSERT_EQ(cricket::CT_NONE, cd->crypto_required()); \ | 34 ASSERT_EQ(cricket::CT_NONE, cd->crypto_required()); \ |
| 35 ASSERT_EQ(0U, cd->cryptos().size()); | 35 ASSERT_EQ(0U, cd->cryptos().size()); |
| 36 #endif | 36 #endif |
| 37 | 37 |
| 38 typedef std::vector<cricket::Candidate> Candidates; | 38 typedef std::vector<cricket::Candidate> Candidates; |
| 39 | 39 |
| 40 using cricket::MediaContentDescription; | 40 using cricket::MediaContentDescription; |
| 41 using cricket::MediaSessionDescriptionFactory; | 41 using cricket::MediaSessionDescriptionFactory; |
| 42 using cricket::MediaContentDirection; | |
| 42 using cricket::MediaSessionOptions; | 43 using cricket::MediaSessionOptions; |
| 43 using cricket::MediaType; | 44 using cricket::MediaType; |
| 44 using cricket::SessionDescription; | 45 using cricket::SessionDescription; |
| 45 using cricket::SsrcGroup; | 46 using cricket::SsrcGroup; |
| 46 using cricket::StreamParams; | 47 using cricket::StreamParams; |
| 47 using cricket::StreamParamsVec; | 48 using cricket::StreamParamsVec; |
| 48 using cricket::TransportDescription; | 49 using cricket::TransportDescription; |
| 49 using cricket::TransportDescriptionFactory; | 50 using cricket::TransportDescriptionFactory; |
| 50 using cricket::TransportInfo; | 51 using cricket::TransportInfo; |
| 51 using cricket::ContentInfo; | 52 using cricket::ContentInfo; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 AudioCodec(126, "speex", 16000, 22000, 1), | 87 AudioCodec(126, "speex", 16000, 22000, 1), |
| 87 AudioCodec(0, "PCMU", 8000, 64000, 1), | 88 AudioCodec(0, "PCMU", 8000, 64000, 1), |
| 88 AudioCodec(127, "iLBC", 8000, 13300, 1), | 89 AudioCodec(127, "iLBC", 8000, 13300, 1), |
| 89 }; | 90 }; |
| 90 | 91 |
| 91 static const AudioCodec kAudioCodecsAnswer[] = { | 92 static const AudioCodec kAudioCodecsAnswer[] = { |
| 92 AudioCodec(102, "iLBC", 8000, 13300, 1), | 93 AudioCodec(102, "iLBC", 8000, 13300, 1), |
| 93 AudioCodec(0, "PCMU", 8000, 64000, 1), | 94 AudioCodec(0, "PCMU", 8000, 64000, 1), |
| 94 }; | 95 }; |
| 95 | 96 |
| 97 static const AudioCodec kAudioCodecsAnswer2[] = { | |
| 98 AudioCodec(0, "PCMU", 8000, 64000, 1), | |
| 99 AudioCodec(127, "iLBC", 8000, 13300, 1), | |
| 100 }; | |
| 101 | |
| 96 static const VideoCodec kVideoCodecs1[] = { | 102 static const VideoCodec kVideoCodecs1[] = { |
| 97 VideoCodec(96, "H264-SVC", 320, 200, 30), | 103 VideoCodec(96, "H264-SVC", 320, 200, 30), |
| 98 VideoCodec(97, "H264", 320, 200, 30)}; | 104 VideoCodec(97, "H264", 320, 200, 30)}; |
| 99 | 105 |
| 100 static const VideoCodec kVideoCodecs2[] = { | 106 static const VideoCodec kVideoCodecs2[] = { |
| 101 VideoCodec(126, "H264", 320, 200, 30), | 107 VideoCodec(126, "H264", 320, 200, 30), |
| 102 VideoCodec(127, "H263", 320, 200, 30)}; | 108 VideoCodec(127, "H263", 320, 200, 30)}; |
| 103 | 109 |
| 104 static const VideoCodec kVideoCodecsAnswer[] = { | 110 static const VideoCodec kVideoCodecsAnswer[] = { |
| 105 VideoCodec(97, "H264", 320, 200, 30)}; | 111 VideoCodec(97, "H264", 320, 200, 30)}; |
| (...skipping 2337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2443 EXPECT_EQ(GetParam(), acd->protocol()); | 2449 EXPECT_EQ(GetParam(), acd->protocol()); |
| 2444 EXPECT_EQ(GetParam(), vcd->protocol()); | 2450 EXPECT_EQ(GetParam(), vcd->protocol()); |
| 2445 } | 2451 } |
| 2446 | 2452 |
| 2447 INSTANTIATE_TEST_CASE_P(MediaProtocolPatternTest, | 2453 INSTANTIATE_TEST_CASE_P(MediaProtocolPatternTest, |
| 2448 MediaProtocolTest, | 2454 MediaProtocolTest, |
| 2449 ::testing::ValuesIn(kMediaProtocols)); | 2455 ::testing::ValuesIn(kMediaProtocols)); |
| 2450 INSTANTIATE_TEST_CASE_P(MediaProtocolDtlsPatternTest, | 2456 INSTANTIATE_TEST_CASE_P(MediaProtocolDtlsPatternTest, |
| 2451 MediaProtocolTest, | 2457 MediaProtocolTest, |
| 2452 ::testing::ValuesIn(kMediaProtocolsDtls)); | 2458 ::testing::ValuesIn(kMediaProtocolsDtls)); |
| 2459 | |
| 2460 TEST_F(MediaSessionDescriptionFactoryTest, TestSetAudioCodecsOld) { | |
| 2461 TransportDescriptionFactory tdf; | |
| 2462 MediaSessionDescriptionFactory sf(&tdf); | |
| 2463 const std::vector<AudioCodec> codecs = MAKE_VECTOR(kAudioCodecs1); | |
| 2464 sf.set_audio_codecs(codecs); | |
| 2465 | |
| 2466 EXPECT_TRUE(sf.audio_codecs() == codecs); | |
| 2467 EXPECT_TRUE(sf.audio_send_codecs() == codecs); | |
| 2468 EXPECT_TRUE(sf.audio_recv_codecs() == codecs); | |
| 2469 } | |
| 2470 | |
| 2471 TEST_F(MediaSessionDescriptionFactoryTest, TestSetAudioCodecs) { | |
| 2472 TransportDescriptionFactory tdf; | |
| 2473 MediaSessionDescriptionFactory sf(&tdf); | |
| 2474 std::vector<AudioCodec> send_codecs = MAKE_VECTOR(kAudioCodecs1); | |
| 2475 std::vector<AudioCodec> recv_codecs = MAKE_VECTOR(kAudioCodecs2); | |
| 2476 | |
| 2477 // The merged list of codecs should contain any send codecs that are also | |
| 2478 // nominally in the recieve codecs list. Payload types should be picked from | |
| 2479 // the send codecs and a number-of-channels of 0 and 1 should be equivalent | |
| 2480 // (set to 1). This equals what happens when the send codecs are used in an | |
| 2481 // offer and the receive codecs are used in the following answer. | |
| 2482 const std::vector<AudioCodec> sendrecv_codecs = | |
| 2483 MAKE_VECTOR(kAudioCodecsAnswer); | |
| 2484 const std::vector<AudioCodec> no_codecs; | |
| 2485 | |
| 2486 RTC_CHECK_EQ(send_codecs[1].name, "iLBC") | |
| 2487 << "Please don't change shared test data!"; | |
| 2488 RTC_CHECK_EQ(recv_codecs[2].name, "iLBC") | |
| 2489 << "Please don't change shared test data!"; | |
| 2490 // Alter iLBC send codec to have zero channels, to test that that is handled | |
| 2491 // properly. | |
| 2492 send_codecs[1].channels = 0; | |
| 2493 | |
| 2494 // Alther iLBC receive codec to be lowercase, to test that case conversions | |
| 2495 // are handled properly. | |
| 2496 recv_codecs[2].name = "ilbc"; | |
| 2497 | |
| 2498 // Test proper merge | |
| 2499 sf.set_audio_codecs(send_codecs, recv_codecs); | |
| 2500 EXPECT_TRUE(sf.audio_send_codecs() == send_codecs); | |
| 2501 EXPECT_TRUE(sf.audio_recv_codecs() == recv_codecs); | |
| 2502 EXPECT_TRUE(sf.audio_codecs() == sendrecv_codecs); | |
| 2503 | |
| 2504 // Test empty send codecs list | |
| 2505 sf.set_audio_codecs(no_codecs, recv_codecs); | |
| 2506 EXPECT_TRUE(sf.audio_send_codecs() == no_codecs); | |
| 2507 EXPECT_TRUE(sf.audio_recv_codecs() == recv_codecs); | |
| 2508 EXPECT_TRUE(sf.audio_codecs() == no_codecs); | |
| 2509 | |
| 2510 // Test empty recv codecs list | |
| 2511 sf.set_audio_codecs(send_codecs, no_codecs); | |
| 2512 EXPECT_TRUE(sf.audio_send_codecs() == send_codecs); | |
| 2513 EXPECT_TRUE(sf.audio_recv_codecs() == no_codecs); | |
| 2514 EXPECT_TRUE(sf.audio_codecs() == no_codecs); | |
| 2515 | |
| 2516 // Test all empty codec lists | |
| 2517 sf.set_audio_codecs(no_codecs, no_codecs); | |
| 2518 EXPECT_TRUE(sf.audio_send_codecs() == no_codecs); | |
| 2519 EXPECT_TRUE(sf.audio_recv_codecs() == no_codecs); | |
| 2520 EXPECT_TRUE(sf.audio_codecs() == no_codecs); | |
| 2521 } | |
| 2522 | |
| 2523 namespace { | |
| 2524 void TestAudioCodecsOffer(MediaContentDirection direction) { | |
| 2525 TransportDescriptionFactory tdf; | |
| 2526 MediaSessionDescriptionFactory sf(&tdf); | |
| 2527 const std::vector<AudioCodec> send_codecs = MAKE_VECTOR(kAudioCodecs1); | |
| 2528 const std::vector<AudioCodec> recv_codecs = MAKE_VECTOR(kAudioCodecs2); | |
| 2529 const std::vector<AudioCodec> sendrecv_codecs = | |
| 2530 MAKE_VECTOR(kAudioCodecsAnswer); | |
| 2531 sf.set_audio_codecs(send_codecs, recv_codecs); | |
| 2532 | |
| 2533 // Don't add a legacy stream whenever we've not provided a stream ourselves. | |
| 2534 sf.set_add_legacy_streams(false); | |
| 2535 MediaSessionOptions opts; | |
| 2536 opts.recv_audio = (direction == cricket::MD_RECVONLY || | |
| 2537 direction == cricket::MD_SENDRECV); | |
| 2538 opts.recv_video = false; | |
| 2539 if (direction == cricket::MD_SENDONLY || direction == cricket::MD_SENDRECV) | |
| 2540 opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | |
| 2541 | |
| 2542 std::unique_ptr<SessionDescription> offer(sf.CreateOffer(opts, NULL)); | |
| 2543 ASSERT_TRUE(offer.get() != NULL); | |
| 2544 const ContentInfo* ac = offer->GetContentByName("audio"); | |
| 2545 | |
| 2546 // If the factory didn't add any audio content to the offer, we cannot check | |
| 2547 // that the codecs put in are right. This happens when we neither want to send | |
| 2548 // nor receive audio. The checks are still in place if at some point we'd | |
| 2549 // instead create an inactive stream. | |
| 2550 if (ac) { | |
| 2551 AudioContentDescription* acd = | |
| 2552 static_cast<AudioContentDescription*>(ac->description); | |
| 2553 // sendrecv and inactive should both present lists as if the channel was to | |
| 2554 // be used for sending and receiving. Inactive essentially means it might | |
| 2555 // eventually be used anything, but we don't know more at this moment. | |
| 2556 if (acd->direction() == cricket::MD_SENDONLY) { | |
| 2557 EXPECT_TRUE(acd->codecs() == send_codecs); | |
| 2558 } else if (acd->direction() == cricket::MD_RECVONLY) { | |
| 2559 EXPECT_TRUE(acd->codecs() == recv_codecs); | |
| 2560 } else { | |
| 2561 EXPECT_TRUE(acd->codecs() == sendrecv_codecs); | |
| 2562 } | |
| 2563 } | |
| 2564 } | |
| 2565 | |
| 2566 void TestAudioCodecsAnswer(MediaContentDirection offer_direction, | |
| 2567 MediaContentDirection answer_direction) { | |
| 2568 TransportDescriptionFactory offer_tdf; | |
| 2569 TransportDescriptionFactory answer_tdf; | |
| 2570 MediaSessionDescriptionFactory offer_factory(&offer_tdf); | |
| 2571 MediaSessionDescriptionFactory answer_factory(&answer_tdf); | |
| 2572 const std::vector<AudioCodec> send_codecs = MAKE_VECTOR(kAudioCodecs1); | |
| 2573 const std::vector<AudioCodec> recv_codecs = MAKE_VECTOR(kAudioCodecs2); | |
| 2574 const std::vector<AudioCodec> answerer_sendrecv_codecs = | |
| 2575 MAKE_VECTOR(kAudioCodecsAnswer); | |
| 2576 const std::vector<AudioCodec> offerer_sendrecv_codecs = | |
| 2577 MAKE_VECTOR(kAudioCodecsAnswer2); | |
| 2578 // Send and receive are from the perspective of the answerer (since we're | |
| 2579 // testing the answer generation). | |
| 2580 offer_factory.set_audio_codecs(recv_codecs, send_codecs); | |
| 2581 answer_factory.set_audio_codecs(send_codecs, recv_codecs); | |
| 2582 | |
| 2583 // Don't add a legacy stream whenever we've not provided a stream ourselves. | |
| 2584 offer_factory.set_add_legacy_streams(false); | |
| 2585 answer_factory.set_add_legacy_streams(false); | |
| 2586 MediaSessionOptions offer_opts; | |
| 2587 offer_opts.recv_audio = (offer_direction == cricket::MD_RECVONLY || | |
| 2588 offer_direction == cricket::MD_SENDRECV); | |
| 2589 offer_opts.recv_video = false; | |
| 2590 if (offer_direction == cricket::MD_SENDONLY || | |
| 2591 offer_direction == cricket::MD_SENDRECV) { | |
| 2592 offer_opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | |
| 2593 } | |
| 2594 | |
| 2595 std::unique_ptr<SessionDescription> offer( | |
| 2596 offer_factory.CreateOffer(offer_opts, NULL)); | |
| 2597 ASSERT_TRUE(offer.get() != NULL); | |
| 2598 | |
| 2599 MediaSessionOptions answer_opts; | |
| 2600 answer_opts.recv_audio = (answer_direction == cricket::MD_RECVONLY || | |
| 2601 answer_direction == cricket::MD_SENDRECV); | |
| 2602 answer_opts.recv_video = false; | |
| 2603 if (answer_direction == cricket::MD_SENDONLY || | |
| 2604 answer_direction == cricket::MD_SENDRECV) { | |
| 2605 answer_opts.AddSendStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1); | |
| 2606 } | |
| 2607 std::unique_ptr<SessionDescription> answer( | |
| 2608 answer_factory.CreateAnswer(offer.get(), answer_opts, NULL)); | |
| 2609 const ContentInfo* ac = answer->GetContentByName("audio"); | |
| 2610 | |
| 2611 // If the factory didn't add any audio content to the answer, we cannot check | |
| 2612 // that the codecs put in are right. This happens when we neither want to send | |
| 2613 // nor receive audio. The checks are still in place if at some point we'd | |
| 2614 // instead create an inactive stream. | |
| 2615 if (ac) { | |
| 2616 const AudioContentDescription* acd = | |
| 2617 static_cast<const AudioContentDescription*>(ac->description); | |
| 2618 EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); | |
| 2619 | |
| 2620 // For offers with sendrecv or inactive, we should never reply with more | |
| 2621 // codecs than offered, with these codec sets. | |
| 2622 if (offer_direction == cricket::MD_SENDRECV || | |
| 2623 offer_direction == cricket::MD_INACTIVE) { | |
| 2624 EXPECT_TRUE(acd->codecs() == offerer_sendrecv_codecs) | |
| 2625 << "Offered: " << MediaContentDirectionToString(offer_direction) | |
| 2626 << ", answerer wants: " | |
| 2627 << MediaContentDirectionToString(answer_direction) | |
| 2628 << "; got: " << MediaContentDirectionToString(acd->direction()); | |
| 2629 } else { | |
| 2630 // Otherwise, the codecs in the answer should depend only on the direction | |
| 2631 // we picked in our answer. | |
| 2632 if (acd->direction() == cricket::MD_SENDONLY) { | |
| 2633 EXPECT_TRUE(acd->codecs() == send_codecs) | |
| 2634 << "Offered: " << MediaContentDirectionToString(offer_direction) | |
| 2635 << ", answerer wants: " | |
| 2636 << MediaContentDirectionToString(answer_direction) | |
| 2637 << "; got: " << MediaContentDirectionToString(acd->direction()); | |
| 2638 } else if (acd->direction() == cricket::MD_RECVONLY) { | |
| 2639 EXPECT_TRUE(acd->codecs() == recv_codecs) | |
| 2640 << "Offered: " << MediaContentDirectionToString(offer_direction) | |
| 2641 << ", answerer wants: " | |
| 2642 << MediaContentDirectionToString(answer_direction) | |
| 2643 << "; got: " << MediaContentDirectionToString(acd->direction()); | |
| 2644 } else { | |
| 2645 EXPECT_TRUE(acd->codecs() == answerer_sendrecv_codecs) | |
| 2646 << "Offered: " << MediaContentDirectionToString(offer_direction) | |
| 2647 << ", answerer wants: " | |
| 2648 << MediaContentDirectionToString(answer_direction) | |
| 2649 << "; got: " << MediaContentDirectionToString(acd->direction()); | |
| 2650 } | |
| 2651 } | |
| 2652 } | |
| 2653 } | |
| 2654 } | |
| 2655 | |
| 2656 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioSendOnlyCodecsOffer) { | |
| 2657 TestAudioCodecsOffer(cricket::MD_SENDONLY); | |
| 2658 } | |
| 2659 | |
| 2660 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioRecvOnlyCodecsOffer) { | |
| 2661 TestAudioCodecsOffer(cricket::MD_RECVONLY); | |
| 2662 } | |
| 2663 | |
| 2664 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioSendRecvCodecsOffer) { | |
| 2665 TestAudioCodecsOffer(cricket::MD_SENDRECV); | |
| 2666 } | |
| 2667 | |
| 2668 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioInactiveCodecsOffer) { | |
| 2669 TestAudioCodecsOffer(cricket::MD_INACTIVE); | |
| 2670 } | |
| 2671 | |
| 2672 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioSendOnlyCodecsAnswer) { | |
|
ossu
2016/05/23 14:18:04
I grouped them by the expected resulting direction
| |
| 2673 TestAudioCodecsAnswer(cricket::MD_RECVONLY, cricket::MD_SENDONLY); | |
| 2674 TestAudioCodecsAnswer(cricket::MD_RECVONLY, cricket::MD_SENDRECV); | |
| 2675 TestAudioCodecsAnswer(cricket::MD_SENDRECV, cricket::MD_SENDONLY); | |
| 2676 } | |
| 2677 | |
| 2678 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioRecvOnlyCodecsAnswer) { | |
| 2679 TestAudioCodecsAnswer(cricket::MD_SENDONLY, cricket::MD_RECVONLY); | |
| 2680 TestAudioCodecsAnswer(cricket::MD_SENDONLY, cricket::MD_SENDRECV); | |
| 2681 TestAudioCodecsAnswer(cricket::MD_SENDRECV, cricket::MD_RECVONLY); | |
| 2682 } | |
| 2683 | |
| 2684 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioSendRecvCodecsAnswer) { | |
| 2685 TestAudioCodecsAnswer(cricket::MD_SENDRECV, cricket::MD_SENDRECV); | |
| 2686 } | |
| 2687 | |
| 2688 TEST_F(MediaSessionDescriptionFactoryTest, TestAudioInactiveCodecsAnswer) { | |
| 2689 TestAudioCodecsAnswer(cricket::MD_INACTIVE, cricket::MD_INACTIVE); | |
| 2690 TestAudioCodecsAnswer(cricket::MD_INACTIVE, cricket::MD_SENDONLY); | |
| 2691 TestAudioCodecsAnswer(cricket::MD_INACTIVE, cricket::MD_RECVONLY); | |
| 2692 TestAudioCodecsAnswer(cricket::MD_INACTIVE, cricket::MD_SENDRECV); | |
| 2693 TestAudioCodecsAnswer(cricket::MD_RECVONLY, cricket::MD_RECVONLY); | |
| 2694 TestAudioCodecsAnswer(cricket::MD_SENDONLY, cricket::MD_SENDONLY); | |
| 2695 TestAudioCodecsAnswer(cricket::MD_RECVONLY, cricket::MD_INACTIVE); | |
| 2696 TestAudioCodecsAnswer(cricket::MD_SENDONLY, cricket::MD_INACTIVE); | |
| 2697 TestAudioCodecsAnswer(cricket::MD_SENDRECV, cricket::MD_INACTIVE); | |
| 2698 } | |
| OLD | NEW |