diff options
author | pbos@webrtc.org <pbos@webrtc.org> | 2015-01-09 15:16:10 +0000 |
---|---|---|
committer | pbos@webrtc.org <pbos@webrtc.org> | 2015-01-09 15:16:10 +0000 |
commit | 2a169640a3225a559f926fe74f1fe1af239e191f (patch) | |
tree | 336f0ce0091c8acf133cc288f634c64ae010d10a /talk | |
parent | 8649fed1b83882d2f25d3c58a3464a0a59a22225 (diff) | |
download | webrtc-2a169640a3225a559f926fe74f1fe1af239e191f.tar.gz |
Support associated payload type when registering Rtx payload type.
Major changes include,
- Add associated payload type for SetRtxSendPayloadType & SetRtxReceivePayloadType.
- Receiver: Restore RTP packets by the new RTX-APT map.
- Sender: Send RTP packets by checking RTX-APT map.
- Add RTX payload type for RED in the default codec list.
BUG=4024
R=pbos@webrtc.org, stefan@webrtc.org
TBR=mflodman@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/26259004
Patch from Changbin Shao <changbin.shao@intel.com>.
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8028 4adac7df-926f-26a2-2b94-8c16560cd09d
Diffstat (limited to 'talk')
-rwxr-xr-x | talk/libjingle_tests.gyp | 6 | ||||
-rw-r--r-- | talk/media/webrtc/fakewebrtcvideoengine.h | 58 | ||||
-rw-r--r-- | talk/media/webrtc/webrtcvideoengine.cc | 62 | ||||
-rw-r--r-- | talk/media/webrtc/webrtcvideoengine.h | 3 | ||||
-rw-r--r-- | talk/media/webrtc/webrtcvideoengine2.cc | 23 | ||||
-rw-r--r-- | talk/media/webrtc/webrtcvideoengine2.h | 1 | ||||
-rw-r--r-- | talk/media/webrtc/webrtcvideoengine2_unittest.cc | 27 | ||||
-rw-r--r-- | talk/media/webrtc/webrtcvideoengine_unittest.cc | 37 |
8 files changed, 145 insertions, 72 deletions
diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp index ac13a4c548..19ce82b670 100755 --- a/talk/libjingle_tests.gyp +++ b/talk/libjingle_tests.gyp @@ -88,10 +88,16 @@ 'target_name': 'libjingle_media_unittest', 'type': 'executable', 'dependencies': [ + '<(DEPTH)/testing/gmock.gyp:gmock', '<(webrtc_root)/base/base_tests.gyp:rtc_base_tests_utils', 'libjingle.gyp:libjingle_media', 'libjingle_unittest_main', ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(DEPTH)/testing/gmock/include', + ], + }, 'sources': [ # TODO(ronghuawu): Reenable this test. # 'media/base/capturemanager_unittest.cc', diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h index aaa2f3bc0b..dff6d01729 100644 --- a/talk/media/webrtc/fakewebrtcvideoengine.h +++ b/talk/media/webrtc/fakewebrtcvideoengine.h @@ -266,8 +266,6 @@ class FakeWebRtcVideoEngine receive_(false), can_transmit_(true), remote_rtx_ssrc_(-1), - rtx_send_payload_type(-1), - rtx_recv_payload_type(-1), rtcp_status_(webrtc::kRtcpNone), key_frame_request_method_(webrtc::kViEKeyFrameRequestNone), tmmbr_(false), @@ -305,8 +303,8 @@ class FakeWebRtcVideoEngine std::map<int, int> ssrcs_; std::map<int, int> rtx_ssrcs_; int remote_rtx_ssrc_; - int rtx_send_payload_type; - int rtx_recv_payload_type; + std::map<int, int> rtx_send_payload_types; + std::map<int, int> rtx_recv_payload_types; std::string cname_; webrtc::ViERTCPMode rtcp_status_; webrtc::ViEKeyFrameRequestMethod key_frame_request_method_; @@ -614,14 +612,30 @@ class FakeWebRtcVideoEngine WEBRTC_ASSERT_CHANNEL(channel); channels_[GetOriginalChannelId(channel)]->receive_bandwidth_ = receive_bandwidth; - }; - int GetRtxSendPayloadType(int channel) { - WEBRTC_CHECK_CHANNEL(channel); - return channels_[channel]->rtx_send_payload_type; } - int GetRtxRecvPayloadType(int channel) { - WEBRTC_CHECK_CHANNEL(channel); - return channels_[channel]->rtx_recv_payload_type; + std::set<int> GetRtxSendPayloadType(int channel) { + std::set<int> rtx_payload_types; + if (channels_.find(channel) == channels_.end()) + return rtx_payload_types; + + std::map<int, int>::const_iterator it; + for (it = channels_[channel]->rtx_send_payload_types.begin(); + it != channels_[channel]->rtx_send_payload_types.end(); ++it) { + rtx_payload_types.insert(it->first); + } + return rtx_payload_types; + } + std::set<int> GetRtxRecvPayloadType(int channel) { + std::set<int> rtx_payload_types; + if (channels_.find(channel) == channels_.end()) + return rtx_payload_types; + + std::map<int, int>::const_iterator it; + for (it = channels_[channel]->rtx_recv_payload_types.begin(); + it != channels_[channel]->rtx_recv_payload_types.end(); ++it) { + rtx_payload_types.insert(it->first); + } + return rtx_payload_types; } int GetRemoteRtxSsrc(int channel) { WEBRTC_CHECK_CHANNEL(channel); @@ -1006,17 +1020,27 @@ class FakeWebRtcVideoEngine WEBRTC_STUB_CONST(GetRemoteSSRC, (const int, unsigned int&)); WEBRTC_STUB_CONST(GetRemoteCSRCs, (const int, unsigned int*)); - WEBRTC_FUNC(SetRtxSendPayloadType, (const int channel, - const uint8 payload_type)) { + WEBRTC_FUNC(SetRtxSendPayloadType, + (const int channel, + const uint8 payload_type, + const uint8 associated_payload_type)) { WEBRTC_CHECK_CHANNEL(channel); - channels_[channel]->rtx_send_payload_type = payload_type; + assert(payload_type >= 0); + assert(associated_payload_type >= 0); + channels_[channel]->rtx_send_payload_types[payload_type] = + associated_payload_type; return 0; } - WEBRTC_FUNC(SetRtxReceivePayloadType, (const int channel, - const uint8 payload_type)) { + WEBRTC_FUNC(SetRtxReceivePayloadType, + (const int channel, + const uint8 payload_type, + const uint8 associated_payload_type)) { WEBRTC_CHECK_CHANNEL(channel); - channels_[channel]->rtx_recv_payload_type = payload_type; + assert(payload_type >= 0); + assert(associated_payload_type >= 0); + channels_[channel]->rtx_recv_payload_types[payload_type] = + associated_payload_type; return 0; } diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc index 689aef35d3..3cce243d31 100644 --- a/talk/media/webrtc/webrtcvideoengine.cc +++ b/talk/media/webrtc/webrtcvideoengine.cc @@ -180,6 +180,13 @@ const int kVideoRtpBufferSize = 65536; const char kVp8CodecName[] = "VP8"; const char kVp9CodecName[] = "VP9"; +const int kDefaultVp8PlType = 100; +const int kDefaultVp9PlType = 101; +const int kDefaultRedPlType = 116; +const int kDefaultUlpfecType = 117; +const int kDefaultRtxVp8PlType = 96; +const int kDefaultRtxRedPlType = 97; + // TODO(ronghuawu): Change to 640x360. const int kDefaultVideoMaxWidth = 640; const int kDefaultVideoMaxHeight = 400; @@ -305,14 +312,16 @@ bool CodecIsInternallySupported(const std::string& codec_name) { std::vector<VideoCodec> DefaultVideoCodecList() { std::vector<VideoCodec> codecs; if (CodecIsInternallySupported(kVp9CodecName)) { - codecs.push_back( - MakeVideoCodecWithDefaultFeedbackParams(101, kVp9CodecName)); + codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType, + kVp9CodecName)); // TODO(andresp): Add rtx codec for vp9 and verify it works. } - codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(100, kVp8CodecName)); - codecs.push_back(MakeRtxCodec(96, 100)); - codecs.push_back(MakeVideoCodec(116, kRedCodecName)); - codecs.push_back(MakeVideoCodec(117, kUlpfecCodecName)); + codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, + kVp8CodecName)); + codecs.push_back(MakeRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType)); + codecs.push_back(MakeVideoCodec(kDefaultRedPlType, kRedCodecName)); + codecs.push_back(MakeRtxCodec(kDefaultRtxRedPlType, kDefaultRedPlType)); + codecs.push_back(MakeVideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); return codecs; } @@ -1729,7 +1738,6 @@ WebRtcVideoMediaChannel::WebRtcVideoMediaChannel( first_receive_ssrc_(kSsrcUnset), receiver_report_ssrc_(kSsrcUnset), num_unsignalled_recv_channels_(0), - send_rtx_type_(-1), send_red_type_(-1), send_fec_type_(-1), sending_(false), @@ -1819,7 +1827,6 @@ bool WebRtcVideoMediaChannel::SetSendCodecs( std::vector<webrtc::VideoCodec> send_codecs; VideoCodec checked_codec; VideoCodec dummy_current; // Will be ignored by CanSendCodec. - std::map<int, int> primary_rtx_pt_mapping; bool nack_enabled = nack_enabled_; bool remb_enabled = remb_enabled_; for (std::vector<VideoCodec>::const_iterator iter = codecs.begin(); @@ -1832,7 +1839,7 @@ bool WebRtcVideoMediaChannel::SetSendCodecs( int rtx_type = iter->id; int rtx_primary_type = -1; if (iter->GetParam(kCodecParamAssociatedPayloadType, &rtx_primary_type)) { - primary_rtx_pt_mapping[rtx_primary_type] = rtx_type; + send_rtx_apt_types_[rtx_type] = rtx_primary_type; } } else if (engine()->CanSendCodec(*iter, dummy_current, &checked_codec)) { webrtc::VideoCodec wcodec; @@ -1897,14 +1904,6 @@ bool WebRtcVideoMediaChannel::SetSendCodecs( // Select the first matched codec. webrtc::VideoCodec& codec(send_codecs[0]); - // Set RTX payload type if primary now active. This value will be used in - // SetSendCodec. - std::map<int, int>::const_iterator rtx_it = - primary_rtx_pt_mapping.find(static_cast<int>(codec.plType)); - if (rtx_it != primary_rtx_pt_mapping.end()) { - send_rtx_type_ = rtx_it->second; - } - if (BitrateIsSet(codec.minBitrate) && BitrateIsSet(codec.maxBitrate) && codec.minBitrate > codec.maxBitrate) { // TODO(pthatcher): This behavior contradicts other behavior in @@ -3831,8 +3830,11 @@ void WebRtcVideoMediaChannel::LogSendCodecChange(const std::string& reason) { << vie_codec.codecSpecific.VP8.keyFrameInterval; } - if (send_rtx_type_ != -1) { - LOG(LS_INFO) << "RTX payload type: " << send_rtx_type_; + std::map<int, int>::const_iterator it; + for (it = send_rtx_apt_types_.begin(); it != send_rtx_apt_types_.end(); + ++it) { + LOG(LS_INFO) << "RTX payload type: " << it->first + << ", associated payload type:" << it->second; } LogSimulcastSubstreams(vie_codec); @@ -3850,7 +3852,6 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs( it != receive_codecs_.end(); ++it) { pt_to_codec[it->plType] = &(*it); } - bool rtx_registered = false; for (std::vector<webrtc::VideoCodec>::iterator it = receive_codecs_.begin(); it != receive_codecs_.end(); ++it) { if (it->codecType == webrtc::kVideoCodecRED) { @@ -3861,11 +3862,6 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs( // If this is an RTX codec we have to verify that it is associated with // a valid video codec which we have RTX support for. if (_stricmp(it->plName, kRtxCodecName) == 0) { - // WebRTC only supports one RTX codec at a time. - if (rtx_registered) { - LOG(LS_ERROR) << "Only one RTX codec at a time is supported."; - return false; - } std::map<int, int>::iterator apt_it = associated_payload_types_.find( it->plType); bool valid_apt = false; @@ -3880,11 +3876,10 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs( return false; } if (engine()->vie()->rtp()->SetRtxReceivePayloadType( - channel_id, it->plType) != 0) { + channel_id, it->plType, apt_it->second) != 0) { LOG_RTCERR2(SetRtxReceivePayloadType, channel_id, it->plType); return false; } - rtx_registered = true; continue; } if (engine()->vie()->codec()->SetReceiveCodec(channel_id, *it) != 0) { @@ -4020,11 +4015,14 @@ bool WebRtcVideoMediaChannel::SetSendParams( // NOTE: SetRtxSendPayloadType must be called after all SSRCs are // configured. Otherwise ssrc's configured after this point will use // the primary PT for RTX. - if (send_rtx_type_ != -1 && - engine()->vie()->rtp()->SetRtxSendPayloadType(channel_id, - send_rtx_type_) != 0) { - LOG_RTCERR2(SetRtxSendPayloadType, channel_id, send_rtx_type_); - return false; + std::map<int, int>::const_iterator it; + for (it = send_rtx_apt_types_.begin(); it != send_rtx_apt_types_.end(); + ++it) { + if (engine()->vie()->rtp()->SetRtxSendPayloadType(channel_id, it->first, + it->second) != 0) { + LOG_RTCERR3(SetRtxSendPayloadType, channel_id, it->first, it->second); + return false; + } } send_channel->set_send_params(send_params); diff --git a/talk/media/webrtc/webrtcvideoengine.h b/talk/media/webrtc/webrtcvideoengine.h index 78a10e0bf0..85d4611b06 100644 --- a/talk/media/webrtc/webrtcvideoengine.h +++ b/talk/media/webrtc/webrtcvideoengine.h @@ -511,7 +511,8 @@ class WebRtcVideoMediaChannel : public rtc::MessageHandler, // Global send side state. SendChannelMap send_channels_; rtc::scoped_ptr<webrtc::VideoCodec> send_codec_; - int send_rtx_type_; + // A map from RTX payload types to their associated payload types. + std::map<int, int> send_rtx_apt_types_; int send_red_type_; int send_fec_type_; bool sending_; diff --git a/talk/media/webrtc/webrtcvideoengine2.cc b/talk/media/webrtc/webrtcvideoengine2.cc index d066eb9c9e..0239c89478 100644 --- a/talk/media/webrtc/webrtcvideoengine2.cc +++ b/talk/media/webrtc/webrtcvideoengine2.cc @@ -121,6 +121,15 @@ static void MergeFecConfig(const webrtc::FecConfig& other, } output->red_payload_type = other.red_payload_type; } + if (other.rtx_payload_type != -1) { + if (output->rtx_payload_type != -1 && + output->rtx_payload_type != other.rtx_payload_type) { + LOG(LS_WARNING) << "Conflict merging rtx_payload_type configs: " + << output->rtx_payload_type << " and " + << other.rtx_payload_type; + } + output->rtx_payload_type = other.rtx_payload_type; + } } } // namespace @@ -2070,6 +2079,7 @@ bool WebRtcVideoChannel2::VideoCodecSettings::operator==( return codec == other.codec && fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && fec.red_payload_type == other.fec.red_payload_type && + fec.rtx_payload_type == other.fec.rtx_payload_type && rtx_payload_type == other.rtx_payload_type; } @@ -2142,17 +2152,24 @@ WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; return std::vector<VideoCodecSettings>(); } - if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { - LOG(LS_ERROR) << "RTX not mapped to regular video codec."; + if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && + payload_codec_type[it->first] != VideoCodec::CODEC_RED) { + LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; return std::vector<VideoCodecSettings>(); } + + if (it->first == fec_settings.red_payload_type) { + fec_settings.rtx_payload_type = it->second; + } } // TODO(pbos): Write tests that figure out that I have not verified that RTX // codecs aren't mapped to bogus payloads. for (size_t i = 0; i < video_codecs.size(); ++i) { video_codecs[i].fec = fec_settings; - if (rtx_mapping[video_codecs[i].codec.id] != 0) { + if (rtx_mapping[video_codecs[i].codec.id] != 0 && + rtx_mapping[video_codecs[i].codec.id] != + fec_settings.red_payload_type) { video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; } } diff --git a/talk/media/webrtc/webrtcvideoengine2.h b/talk/media/webrtc/webrtcvideoengine2.h index 2318971db2..52428d37b8 100644 --- a/talk/media/webrtc/webrtcvideoengine2.h +++ b/talk/media/webrtc/webrtcvideoengine2.h @@ -285,7 +285,6 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, struct VideoCodecSettings { VideoCodecSettings(); - bool operator ==(const VideoCodecSettings& other) const; VideoCodec codec; diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc index 93660a5722..7ceabcabc4 100644 --- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc @@ -34,6 +34,7 @@ #include "talk/media/webrtc/fakewebrtcvideoengine.h" #include "talk/media/webrtc/simulcast.h" #include "talk/media/webrtc/webrtcvideochannelfactory.h" +#include "talk/media/webrtc/webrtcvideoengine.h" #include "talk/media/webrtc/webrtcvideoengine2.h" #include "talk/media/webrtc/webrtcvideoengine2_unittest.h" #include "talk/media/webrtc/webrtcvoiceengine.h" @@ -73,6 +74,19 @@ void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) { cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir))); } +void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config, + const std::map<int, int>& rtx_types) { + std::map<int, int>::const_iterator it; + it = rtx_types.find(config.encoder_settings.payload_type); + EXPECT_TRUE(it != rtx_types.end() && + it->second == config.rtp.rtx.payload_type); + + if (config.rtp.fec.rtx_payload_type != -1) { + it = rtx_types.find(config.rtp.fec.red_payload_type); + EXPECT_TRUE(it != rtx_types.end() && + it->second == config.rtp.fec.rtx_payload_type); + } +} } // namespace namespace cricket { @@ -349,7 +363,11 @@ class WebRtcVideoEngine2Test : public ::testing::Test { } else if (engine_codecs[i].name == "ulpfec") { default_ulpfec_codec_ = engine_codecs[i]; } else if (engine_codecs[i].name == "rtx") { - default_rtx_codec_ = engine_codecs[i]; + int associated_payload_type; + if (engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType, + &associated_payload_type)) { + default_apt_rtx_types_[associated_payload_type] = engine_codecs[i].id; + } } else if (!codec_set) { default_codec_ = engine_codecs[i]; codec_set = true; @@ -388,7 +406,7 @@ class WebRtcVideoEngine2Test : public ::testing::Test { VideoCodec default_codec_; VideoCodec default_red_codec_; VideoCodec default_ulpfec_codec_; - VideoCodec default_rtx_codec_; + std::map<int, int> default_apt_rtx_types_; }; TEST_F(WebRtcVideoEngine2Test, ConfiguresAvSyncForFirstReceiveChannel) { @@ -431,7 +449,7 @@ TEST_F(WebRtcVideoEngine2Test, ConfiguresAvSyncForFirstReceiveChannel) { TEST_F(WebRtcVideoEngine2Test, FindCodec) { const std::vector<cricket::VideoCodec>& c = engine_.codecs(); - EXPECT_EQ(4U, c.size()); + EXPECT_EQ(cricket::DefaultVideoCodecList().size(), c.size()); cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0); EXPECT_TRUE(engine_.FindCodec(vp8)); @@ -1583,8 +1601,7 @@ TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) { EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size()); EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]); - EXPECT_EQ(static_cast<int>(default_rtx_codec_.id), - config.rtp.rtx.payload_type); + VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_); // TODO(juberti): Check RTCP, PLI, TMMBR. } diff --git a/talk/media/webrtc/webrtcvideoengine_unittest.cc b/talk/media/webrtc/webrtcvideoengine_unittest.cc index 24e9af2835..93560a9b6a 100644 --- a/talk/media/webrtc/webrtcvideoengine_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine_unittest.cc @@ -38,6 +38,8 @@ #include "talk/media/webrtc/webrtcvideoframe.h" #include "talk/media/webrtc/webrtcvoiceengine.h" #include "talk/session/media/mediasession.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/fakecpumonitor.h" #include "webrtc/base/gunit.h" #include "webrtc/base/logging.h" @@ -754,7 +756,8 @@ TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithRtx) { EXPECT_FALSE(vie_.ReceiveCodecRegistered(channel_num, wcodec)); // The RTX payload type should have been set. - EXPECT_EQ(rtx_codec.id, vie_.GetRtxRecvPayloadType(channel_num)); + EXPECT_THAT(vie_.GetRtxRecvPayloadType(channel_num), + ::testing::ElementsAre(rtx_codec.id)); } // Test that RTX packets are routed to the default video channel if @@ -2079,7 +2082,8 @@ TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithExternalH264) { codecs.push_back(rtx_codec); EXPECT_TRUE(channel_->SetSendCodecs(codecs)); - EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num)); + EXPECT_THAT(vie_.GetRtxSendPayloadType(channel_num), + ::testing::ElementsAre(96)); cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcs1[0]); @@ -2117,7 +2121,8 @@ TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithVP8AndExternalH264) { // The first matched codec should be set, i.e., H.264. - EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num)); + EXPECT_THAT(vie_.GetRtxSendPayloadType(channel_num), + ::testing::ElementsAre(96, 97)); cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcs1[0]); @@ -2154,7 +2159,8 @@ TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithExternalH264) { codecs.push_back(rtx_codec); EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); - EXPECT_EQ(96, vie_.GetRtxRecvPayloadType(channel_num)); + EXPECT_THAT(vie_.GetRtxRecvPayloadType(channel_num), + ::testing::ElementsAre(96)); cricket::StreamParams params = cricket::StreamParams::CreateLegacy(kSsrcs1[0]); @@ -2189,17 +2195,21 @@ TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithVP8AndExternalH264) { cricket::VideoCodec rtx_codec2(96, "rtx", 0, 0, 0, 0); rtx_codec2.SetParam("apt", kVP8Codec.id); codecs.push_back(kVP8Codec); - codecs.push_back(rtx_codec); - // Should fail since WebRTC only supports one RTX codec at a time. - EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); + codecs.push_back(rtx_codec2); + // Now WebRTC supports setting multiple RTX codecs at a time. + EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); + EXPECT_THAT(vie_.GetRtxRecvPayloadType(channel_num), + ::testing::ElementsAre(96, 97)); codecs.pop_back(); - // One RTX codec should be fine. EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); - // The RTX payload type should have been set. - EXPECT_EQ(rtx_codec.id, vie_.GetRtxRecvPayloadType(channel_num)); + // TODO(changbin): The Rtx key can still be found from the Rtx-Apt map + // if the new codec list doesn't assign it with a new value. + // Should pass a map to SetRtxRecvPayloadType in future. + EXPECT_THAT(vie_.GetRtxRecvPayloadType(channel_num), + ::testing::ElementsAre(96, 97)); } #endif @@ -2249,7 +2259,7 @@ TEST_F(WebRtcVideoEngineTestFake, CaptureFrameTimestampToNtpTimestamp) { TEST_F(WebRtcVideoEngineTest, FindCodec) { // We should not need to init engine in order to get codecs. const std::vector<cricket::VideoCodec>& c = engine_.codecs(); - EXPECT_EQ(4U, c.size()); + EXPECT_EQ(cricket::DefaultVideoCodecList().size(), c.size()); cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0); EXPECT_TRUE(engine_.FindCodec(vp8)); @@ -2296,7 +2306,7 @@ TEST_F(WebRtcVideoEngineTest, RtxCodecHasAptSet) { std::vector<cricket::VideoCodec>::const_iterator it; bool apt_checked = false; for (it = engine_.codecs().begin(); it != engine_.codecs().end(); ++it) { - if (_stricmp(cricket::kRtxCodecName, it->name.c_str()) && it->id != 96) { + if (_stricmp(cricket::kRtxCodecName, it->name.c_str()) || it->id != 96) { continue; } int apt; @@ -3202,7 +3212,8 @@ TEST_F(WebRtcVideoEngineSimulcastTestFake, TestStreamWithRtx) { EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); // RTX payload type should now be set. - EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num)); + EXPECT_THAT(vie_.GetRtxSendPayloadType(channel_num), + ::testing::ElementsAre(96)); // Verify all SSRCs are set after SetSendCodecs. EXPECT_EQ(3, vie_.GetNumSsrcs(channel_num)); |