diff --git a/talk/app/webrtc/mediaconstraintsinterface.cc b/talk/app/webrtc/mediaconstraintsinterface.cc index 72c5ffca05..e0350d3752 100644 --- a/talk/app/webrtc/mediaconstraintsinterface.cc +++ b/talk/app/webrtc/mediaconstraintsinterface.cc @@ -86,6 +86,12 @@ const char MediaConstraintsInterface::kCpuOveruseThreshold[] = "googCpuOveruseThreshold"; const char MediaConstraintsInterface::kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage"; +const char MediaConstraintsInterface::kHighStartBitrate[] = + "googHighStartBitrate"; +const char MediaConstraintsInterface::kHighBitrate[] = + "googHighBitrate"; +const char MediaConstraintsInterface::kVeryHighBitrate[] = + "googVeryHighBitrate"; // Constraint keys for CreateOffer / CreateAnswer defined in W3C specification. const char MediaConstraintsInterface::kOfferToReceiveAudio[] = diff --git a/talk/app/webrtc/mediaconstraintsinterface.h b/talk/app/webrtc/mediaconstraintsinterface.h index 8c1ba17be7..7030a88189 100644 --- a/talk/app/webrtc/mediaconstraintsinterface.h +++ b/talk/app/webrtc/mediaconstraintsinterface.h @@ -100,6 +100,9 @@ class MediaConstraintsInterface { static const char kCpuUnderuseThreshold[]; static const char kCpuOveruseThreshold[]; static const char kCpuOveruseEncodeUsage[]; + static const char kHighStartBitrate[]; // googHighStartBitrate + static const char kHighBitrate[]; // googHighBitrate + static const char kVeryHighBitrate[]; // googVeryHighBitrate // Constraint keys for CreateOffer / CreateAnswer // Specified by the W3C PeerConnection spec diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc index af9d205d1f..50221ac992 100644 --- a/talk/app/webrtc/webrtcsession.cc +++ b/talk/app/webrtc/webrtcsession.cc @@ -578,6 +578,30 @@ bool WebRtcSession::Initialize( video_options_.use_improved_wifi_bandwidth_estimator.Set(value); } + if (FindConstraint( + constraints, + MediaConstraintsInterface::kHighStartBitrate, + &value, + NULL)) { + video_options_.video_start_bitrate.Set(cricket::kHighStartBitrate); + } + + if (FindConstraint( + constraints, + MediaConstraintsInterface::kVeryHighBitrate, + &value, + NULL)) { + video_options_.video_highest_bitrate.Set( + cricket::VideoOptions::VERY_HIGH); + } else if (FindConstraint( + constraints, + MediaConstraintsInterface::kHighBitrate, + &value, + NULL)) { + video_options_.video_highest_bitrate.Set( + cricket::VideoOptions::HIGH); + } + const cricket::VideoCodec default_codec( JsepSessionDescription::kDefaultVideoCodecId, JsepSessionDescription::kDefaultVideoCodecName, diff --git a/talk/media/base/mediachannel.h b/talk/media/base/mediachannel.h index 873c1ffeec..9bdf4d9f46 100644 --- a/talk/media/base/mediachannel.h +++ b/talk/media/base/mediachannel.h @@ -62,6 +62,7 @@ class VideoRenderer; const int kMinRtpHeaderExtensionId = 1; const int kMaxRtpHeaderExtensionId = 255; const int kScreencastDefaultFps = 5; +const int kHighStartBitrate = 1500; // Used in AudioOptions and VideoOptions to signify "unset" values. template @@ -441,7 +442,7 @@ struct VideoOptions { // Enable WebRTC leaky bucket when sending media packets. Settable video_leaky_bucket; // Set highest bitrate mode for video. - Settable video_highest_bitrate; + Settable video_highest_bitrate; // Enable WebRTC Cpu Overuse Detection, which is a new version of the CPU // adaptation algorithm. So this option will override the // |adapt_input_to_cpu_usage|. diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc index f48596afcf..bc7b3d1e66 100644 --- a/talk/media/webrtc/webrtcvideoengine.cc +++ b/talk/media/webrtc/webrtcvideoengine.cc @@ -36,6 +36,7 @@ #include #include "talk/base/basictypes.h" +#include "talk/base/bind.h" #include "talk/base/buffer.h" #include "talk/base/byteorder.h" #include "talk/base/common.h" @@ -3088,8 +3089,18 @@ bool WebRtcVideoMediaChannel::GetVideoAdapter( return true; } +void WebRtcVideoMediaChannel::OnFrameFromCapturer(VideoCapturer* capturer, + const VideoFrame* frame) { + // This method is called from the capturer thread while the rest of the + // WebRtcVideoMediaChannel is run on the worker thread. + engine_->worker_thread()->Invoke( + Bind(&WebRtcVideoMediaChannel::SendFrame, this, capturer, frame)); +} + void WebRtcVideoMediaChannel::SendFrame(VideoCapturer* capturer, const VideoFrame* frame) { + // TODO(ronghuawu): Reenable once webrtc 3125 is fixed. + // ASSERT(engine_->worker_thread() == talk_base::Thread::Current()); // If the |capturer| is registered to any send channel, then send the frame // to those send channels. bool capturer_is_channel_owned = false; @@ -4037,8 +4048,8 @@ bool WebRtcVideoMediaChannel::SetLocalRtxSsrc(int channel_id, void WebRtcVideoMediaChannel::MaybeConnectCapturer(VideoCapturer* capturer) { if (capturer != NULL && GetSendChannelNum(capturer) == 1) { - capturer->SignalVideoFrame.connect(this, - &WebRtcVideoMediaChannel::SendFrame); + capturer->SignalVideoFrame.connect( + this, &WebRtcVideoMediaChannel::OnFrameFromCapturer); } } diff --git a/talk/media/webrtc/webrtcvideoengine.h b/talk/media/webrtc/webrtcvideoengine.h index 1d36ab19a3..968d2c0d4d 100644 --- a/talk/media/webrtc/webrtcvideoengine.h +++ b/talk/media/webrtc/webrtcvideoengine.h @@ -292,9 +292,7 @@ class WebRtcVideoMediaChannel : public talk_base::MessageHandler, uint32 send_ssrc() const { return 0; } bool GetRenderer(uint32 ssrc, VideoRenderer** renderer); bool GetVideoAdapter(uint32 ssrc, CoordinatedVideoAdapter** video_adapter); - void SendFrame(VideoCapturer* capturer, const VideoFrame* frame); - bool SendFrame(WebRtcVideoChannelSendInfo* channel_info, - const VideoFrame* frame, bool is_screencast); + void OnFrameFromCapturer(VideoCapturer* capturer, const VideoFrame* frame); // Thunk functions for use with HybridVideoEngine void OnLocalFrame(VideoCapturer* capturer, const VideoFrame* frame) { @@ -416,6 +414,9 @@ class WebRtcVideoMediaChannel : public talk_base::MessageHandler, // to one send channel, i.e. the last send channel. void MaybeDisconnectCapturer(VideoCapturer* capturer); + void SendFrame(VideoCapturer* capturer, const VideoFrame* frame); + bool SendFrame(WebRtcVideoChannelSendInfo* channel_info, + const VideoFrame* frame, bool is_screencast); bool RemoveRecvStreamInternal(uint32 ssrc); // Global state. diff --git a/talk/media/webrtc/webrtcvideoengine_unittest.cc b/talk/media/webrtc/webrtcvideoengine_unittest.cc index a61b8d8a3d..b436ce23a6 100644 --- a/talk/media/webrtc/webrtcvideoengine_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine_unittest.cc @@ -128,7 +128,7 @@ class WebRtcVideoEngineTestFake : public testing::Test, return false; } cricket::FakeVideoCapturer capturer; - channel_->SendFrame(&capturer, &frame); + channel_->OnFrameFromCapturer(&capturer, &frame); return true; } bool SendI420ScreencastFrame(int width, int height) { @@ -145,7 +145,7 @@ class WebRtcVideoEngineTestFake : public testing::Test, } cricket::FakeVideoCapturer capturer; capturer.SetScreencast(true); - channel_->SendFrame(&capturer, &frame); + channel_->OnFrameFromCapturer(&capturer, &frame); return true; } void VerifyCodecFeedbackParams(const cricket::VideoCodec& codec) {