From a27342b7afb03906813d3efb214d8bae7ad0b7b8 Mon Sep 17 00:00:00 2001 From: "buildbot@webrtc.org" Date: Mon, 4 Aug 2014 15:22:32 +0000 Subject: [PATCH] (Auto)update libjingle 72446860-> 72550257 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6818 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/media/webrtc/webrtcvideoengine.cc | 25 +++- .../webrtc/webrtcvideoengine_unittest.cc | 139 ++++++++++++++++++ 2 files changed, 156 insertions(+), 8 deletions(-) diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc index 1491a9f0c8..7afe5de6b7 100644 --- a/talk/media/webrtc/webrtcvideoengine.cc +++ b/talk/media/webrtc/webrtcvideoengine.cc @@ -3786,6 +3786,7 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs( it != receive_codecs_.end(); ++it) { pt_to_codec[it->plType] = &(*it); } + bool rtx_registered = false; for (std::vector::iterator it = receive_codecs_.begin(); it != receive_codecs_.end(); ++it) { if (it->codecType == webrtc::kVideoCodecRED) { @@ -3796,16 +3797,18 @@ 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::iterator apt_it = associated_payload_types_.find( it->plType); bool valid_apt = false; if (apt_it != associated_payload_types_.end()) { std::map::iterator codec_it = pt_to_codec.find(apt_it->second); - // We currently only support RTX associated with VP8 due to limitations - // in webrtc where only one RTX payload type can be registered. - valid_apt = codec_it != pt_to_codec.end() && - _stricmp(codec_it->second->plName, kVp8CodecName) == 0; + valid_apt = codec_it != pt_to_codec.end(); } if (!valid_apt) { LOG(LS_ERROR) << "The RTX codec isn't associated with a known and " @@ -3817,6 +3820,7 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs( LOG_RTCERR2(SetRtxReceivePayloadType, channel_id, it->plType); return false; } + rtx_registered = true; continue; } if (engine()->vie()->codec()->SetReceiveCodec(channel_id, *it) != 0) { @@ -3926,10 +3930,13 @@ bool WebRtcVideoMediaChannel::MaybeResetVieSendCodec( options_.screencast_min_bitrate.GetWithDefaultIfUnset(0); bool leaky_bucket = options_.video_leaky_bucket.GetWithDefaultIfUnset(true); bool reset_send_codec = - target_width != cur_width || target_height != cur_height || + target_width != cur_width || target_height != cur_height; + if (vie_codec.codecType == webrtc::kVideoCodecVP8) { + reset_send_codec = reset_send_codec || automatic_resize != vie_codec.codecSpecific.VP8.automaticResizeOn || enable_denoising != vie_codec.codecSpecific.VP8.denoisingOn || vp8_frame_dropping != vie_codec.codecSpecific.VP8.frameDroppingOn; + } if (reset_send_codec) { // Set the new codec on vie. @@ -3940,9 +3947,11 @@ bool WebRtcVideoMediaChannel::MaybeResetVieSendCodec( vie_codec.minBitrate = target_codec.minBitrate; vie_codec.maxBitrate = target_codec.maxBitrate; vie_codec.targetBitrate = 0; - vie_codec.codecSpecific.VP8.automaticResizeOn = automatic_resize; - vie_codec.codecSpecific.VP8.denoisingOn = enable_denoising; - vie_codec.codecSpecific.VP8.frameDroppingOn = vp8_frame_dropping; + if (vie_codec.codecType == webrtc::kVideoCodecVP8) { + vie_codec.codecSpecific.VP8.automaticResizeOn = automatic_resize; + vie_codec.codecSpecific.VP8.denoisingOn = enable_denoising; + vie_codec.codecSpecific.VP8.frameDroppingOn = vp8_frame_dropping; + } MaybeChangeBitrates(channel_id, &vie_codec); if (engine()->vie()->codec()->SetSendCodec(channel_id, vie_codec) != 0) { diff --git a/talk/media/webrtc/webrtcvideoengine_unittest.cc b/talk/media/webrtc/webrtcvideoengine_unittest.cc index 9993a9ee59..8533a51a31 100644 --- a/talk/media/webrtc/webrtcvideoengine_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine_unittest.cc @@ -59,6 +59,7 @@ static const cricket::VideoCodec kVP8Codec270p(100, "VP8", 480, 270, 30, 0); static const cricket::VideoCodec kVP8Codec180p(100, "VP8", 320, 180, 30, 0); static const cricket::VideoCodec kVP8Codec(100, "VP8", 640, 400, 30, 0); +static const cricket::VideoCodec kH264Codec(127, "H264", 640, 400, 30, 0); static const cricket::VideoCodec kRedCodec(101, "red", 0, 0, 0, 0); static const cricket::VideoCodec kUlpFecCodec(102, "ulpfec", 0, 0, 0, 0); static const cricket::VideoCodec* const kVideoCodecs[] = { @@ -2114,6 +2115,144 @@ TEST_F(WebRtcVideoEngineTestFake, UpdateEncoderCodecsAfterSetFactory) { EXPECT_TRUE(channel_->RemoveSendStream(kSsrc)); } +#ifdef USE_WEBRTC_DEV_BRANCH +TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithExternalH264) { + encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + engine_.SetExternalEncoderFactory(&encoder_factory_); + EXPECT_TRUE(SetupEngine()); + int channel_num = vie_.GetLastChannel(); + + std::vector codecs; + codecs.push_back(kH264Codec); + cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); + rtx_codec.SetParam("apt", kH264Codec.id); + codecs.push_back(rtx_codec); + EXPECT_TRUE(channel_->SetSendCodecs(codecs)); + + EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num)); + + cricket::StreamParams params = + cricket::StreamParams::CreateLegacy(kSsrcs1[0]); + params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]); + EXPECT_TRUE(channel_->AddSendStream(params)); + + EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num)); + EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num)); + EXPECT_EQ(static_cast(kRtxSsrcs1[0]), vie_.GetRtxSsrc(channel_num, 0)); + + EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 127)); + EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); + EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); + + EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs1[0])); +} + +TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithVP8AndExternalH264) { + encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + engine_.SetExternalEncoderFactory(&encoder_factory_); + EXPECT_TRUE(SetupEngine()); + int channel_num = vie_.GetLastChannel(); + + std::vector codecs; + codecs.push_back(kH264Codec); + cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); + rtx_codec.SetParam("apt", kH264Codec.id); + codecs.push_back(rtx_codec); + codecs.push_back(kVP8Codec); + cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0); + rtx_codec2.SetParam("apt", kVP8Codec.id); + codecs.push_back(rtx_codec2); + + EXPECT_TRUE(channel_->SetSendCodecs(codecs)); + + // The first matched codec should be set, i.e., H.264. + + EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num)); + + cricket::StreamParams params = + cricket::StreamParams::CreateLegacy(kSsrcs1[0]); + params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]); + EXPECT_TRUE(channel_->AddSendStream(params)); + + EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num)); + EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num)); + EXPECT_EQ(static_cast(kRtxSsrcs1[0]), vie_.GetRtxSsrc(channel_num, 0)); + + EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 127)); + EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); + EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); + + EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs1[0])); +} + +TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithExternalH264) { + // WebRtcVideoEngine assumes that if we have encode support for a codec, we + // also have decode support. It doesn't support decode only support. Therefore + // we here have to register both an encoder and a decoder factory with H264 + // support, to be able to test the decoder factory. + encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264); + EXPECT_TRUE(SetupEngine()); + engine_.SetExternalEncoderFactory(&encoder_factory_); + engine_.SetExternalDecoderFactory(&decoder_factory_); + int channel_num = vie_.GetLastChannel(); + + std::vector codecs; + codecs.push_back(kH264Codec); + cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); + rtx_codec.SetParam("apt", kH264Codec.id); + codecs.push_back(rtx_codec); + EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); + + EXPECT_EQ(96, vie_.GetRtxRecvPayloadType(channel_num)); + + cricket::StreamParams params = + cricket::StreamParams::CreateLegacy(kSsrcs1[0]); + params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]); + EXPECT_TRUE(channel_->AddRecvStream(params)); + + EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num)); + EXPECT_EQ(static_cast(kRtxSsrcs1[0]), + vie_.GetRemoteRtxSsrc(channel_num)); + + EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 127)); + EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); + EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders()); + + EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcs1[0])); +} + +TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithVP8AndExternalH264) { + encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); + decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264); + EXPECT_TRUE(SetupEngine()); + engine_.SetExternalEncoderFactory(&encoder_factory_); + engine_.SetExternalDecoderFactory(&decoder_factory_); + int channel_num = vie_.GetLastChannel(); + + std::vector codecs; + cricket::VideoCodec rtx_codec(97, "rtx", 0, 0, 0, 0); + rtx_codec.SetParam("apt", kH264Codec.id); + codecs.push_back(kH264Codec); + codecs.push_back(rtx_codec); + + 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.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)); +} +#endif + // Tests that OnReadyToSend will be propagated into ViE. TEST_F(WebRtcVideoEngineTestFake, OnReadyToSend) { EXPECT_TRUE(SetupEngine());