diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc index c595c9981..4a4e29a06 100644 --- a/talk/media/webrtc/webrtcvideoengine.cc +++ b/talk/media/webrtc/webrtcvideoengine.cc @@ -66,18 +66,6 @@ namespace { -cricket::VideoFormat CreateVideoFormat(int width, int height, int framerate) { - return cricket::VideoFormat( - width, - height, - cricket::VideoFormat::FpsToInterval(framerate), - cricket::FOURCC_ANY); -} - -cricket::VideoFormat VideoFormatFromCodec(const cricket::VideoCodec& codec) { - return CreateVideoFormat(codec.width, codec.height, codec.framerate); -} - template bool Changed(cricket::Settable proposed, cricket::Settable original) { @@ -184,12 +172,10 @@ static bool IsRembEnabled(const VideoCodec& codec) { } struct FlushBlackFrameData : public rtc::MessageData { - FlushBlackFrameData(uint32 s, int64 t, int i) - : ssrc(s), timestamp(t), interval(i) { + FlushBlackFrameData(uint32 s, int64 t) : ssrc(s), timestamp(t) { } uint32 ssrc; int64 timestamp; - int interval; }; class WebRtcRenderAdapter : public webrtc::ExternalRenderer { @@ -616,6 +602,7 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> { video_capturer_(NULL), encoder_observer_(channel_id), external_capture_(external_capture), + interval_(0), cpu_monitor_(cpu_monitor), old_adaptation_changes_(0) { } @@ -638,11 +625,20 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> { } void set_video_format(const VideoFormat& video_format) { video_format_ = video_format; + if (video_format_ != cricket::VideoFormat()) { + interval_ = video_format_.interval; + } CoordinatedVideoAdapter* adapter = video_adapter(); if (adapter) { adapter->OnOutputFormatRequest(video_format_); } } + void set_interval(int64 interval) { + if (video_format() == cricket::VideoFormat()) { + interval_ = interval; + } + } + int64 interval() { return interval_; } int CurrentAdaptReason() const { if (!video_adapter()) { @@ -661,8 +657,11 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> { void set_stream_params(const StreamParams& sp) { stream_params_.reset(new StreamParams(sp)); } - bool IsActive() { return stream_params() != NULL; } - void Deactivate() { stream_params_.reset(); } + void ClearStreamParams() { stream_params_.reset(); } + bool has_ssrc(uint32 local_ssrc) const { + return !stream_params_ ? false : + stream_params_->has_ssrc(local_ssrc); + } WebRtcLocalStreamInfo* local_stream_info() { return &local_stream_info_; } @@ -840,6 +839,8 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> { WebRtcLocalStreamInfo local_stream_info_; + int64 interval_; + rtc::CpuMonitor* cpu_monitor_; rtc::scoped_ptr overuse_observer_; @@ -1102,8 +1103,11 @@ bool WebRtcVideoEngine::SetDefaultCodec(const VideoCodec& codec) { } ASSERT(!video_codecs_.empty()); - default_codec_format_ = VideoFormatFromCodec(video_codecs_[0]); - + default_codec_format_ = VideoFormat( + video_codecs_[0].width, + video_codecs_[0].height, + VideoFormat::FpsToInterval(video_codecs_[0].framerate), + FOURCC_ANY); return true; } @@ -1770,15 +1774,15 @@ bool WebRtcVideoMediaChannel::MaybeRegisterExternalEncoder( const webrtc::VideoCodec& codec) { // Codec type not supported or encoder already registered, so // nothing to do. - if (!engine()->IsExternalEncoderCodecType(codec.codecType) || - send_channel->IsEncoderRegistered(codec.plType)) { + if (!engine()->IsExternalEncoderCodecType(codec.codecType) + || send_channel->IsEncoderRegistered(codec.plType)) { return true; } webrtc::VideoEncoder* encoder = engine()->CreateExternalEncoder(codec.codecType); if (!encoder) { - // No external encoder created, so nothing to do. + // No encoder factor, so nothing to do. return true; } @@ -1893,7 +1897,7 @@ bool WebRtcVideoMediaChannel::AddSendStream(const StreamParams& sp) { // If the default channel is already used for sending create a new channel // otherwise use the default channel for sending. int channel_id = kChannelIdUnset; - if (!DefaultSendChannelIsActive()) { + if (!DefaultSendChannelInUse()) { channel_id = default_channel_id_; } else { if (!CreateChannel(ssrc_key, MD_SEND, &channel_id)) { @@ -1951,9 +1955,9 @@ bool WebRtcVideoMediaChannel::RemoveSendStream(uint32 ssrc) { } WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrcKey(ssrc_key); int channel_id = send_channel->channel_id(); - if (IsDefaultChannelId(channel_id) && !send_channel->IsActive()) { - // Default channel will still exist. However, there is no stream - // to remove. + if (IsDefaultChannelId(channel_id) && !send_channel->stream_params()) { + // Default channel will still exist. However, if stream_params() is NULL + // there is no stream to remove. return false; } if (sending_) { @@ -1975,7 +1979,7 @@ bool WebRtcVideoMediaChannel::RemoveSendStream(uint32 ssrc) { // The receive channels depend on the default channel, recycle it instead. if (IsDefaultChannelId(channel_id)) { SetCapturer(GetDefaultSendChannelSsrc(), NULL); - send_channel->Deactivate(); + send_channel->ClearStreamParams(); } else { return DeleteSendChannel(ssrc_key); } @@ -1991,7 +1995,7 @@ bool WebRtcVideoMediaChannel::AddRecvStream(const StreamParams& sp) { // TODO(zhurunz) Remove this once BWE works properly across different send // and receive channels. // Reuse default channel for recv stream in 1:1 call. - if (!ConferenceModeIsEnabled() && first_receive_ssrc_ == kSsrcUnset) { + if (!InConferenceMode() && first_receive_ssrc_ == kSsrcUnset) { LOG(LS_INFO) << "Recv stream " << sp.first_ssrc() << " reuse default channel #" << default_channel_id_; @@ -2207,11 +2211,11 @@ bool WebRtcVideoMediaChannel::SendIntraFrame() { bool WebRtcVideoMediaChannel::HasReadySendChannels() { return !send_channels_.empty() && - ((send_channels_.size() > 1) || DefaultSendChannelIsActive()); + ((send_channels_.size() > 1) || DefaultSendChannelInUse()); } -bool WebRtcVideoMediaChannel::DefaultSendChannelIsActive() { - return GetDefaultSendChannel() && GetDefaultSendChannel()->IsActive(); +bool WebRtcVideoMediaChannel::DefaultSendChannelInUse() { + return GetDefaultSendChannel() && GetDefaultSendChannel()->stream_params(); } bool WebRtcVideoMediaChannel::GetSendChannelSsrcKey(uint32 local_ssrc, @@ -2236,8 +2240,7 @@ bool WebRtcVideoMediaChannel::GetSendChannelSsrcKey(uint32 local_ssrc, for (SendChannelMap::iterator iter = send_channels_.begin(); iter != send_channels_.end(); ++iter) { WebRtcVideoChannelSendInfo* send_channel = iter->second; - if (send_channel->stream_params() != NULL && - send_channel->stream_params()->has_ssrc(local_ssrc)) { + if (send_channel->has_ssrc(local_ssrc)) { *ssrc_key = iter->first; return true; } @@ -2281,7 +2284,7 @@ bool WebRtcVideoMediaChannel::CreateSendChannelSsrcKey(uint32 local_ssrc, // this point a duplicate SSRC has been detected. return false; } - if (!DefaultSendChannelIsActive()) { + if (!DefaultSendChannelInUse()) { // |ssrc_key| should be kDefaultChannelSsrcKey here as the default // channel should be re-used whenever it is not used. *ssrc_key = kDefaultChannelSsrcKey; @@ -2307,7 +2310,7 @@ int WebRtcVideoMediaChannel::GetSendChannelNum(VideoCapturer* capturer) { } uint32 WebRtcVideoMediaChannel::GetDefaultSendChannelSsrc() { - if (!DefaultSendChannelIsActive()) { + if (!DefaultSendChannelInUse()) { return 0; } return GetDefaultSendChannel()->stream_params()->first_ssrc(); @@ -2415,7 +2418,8 @@ bool WebRtcVideoMediaChannel::GetStats(const StatsOptions& options, WebRtcVideoChannelSendInfo* send_channel = iter->second; const int channel_id = send_channel->channel_id(); VideoSenderInfo sinfo; - if (!send_channel->IsActive()) { + const StreamParams* send_params = send_channel->stream_params(); + if (!send_params) { // This should only happen if the default vie channel is not in use. // This can happen if no streams have ever been added or the stream // corresponding to the default channel has been removed. Note that @@ -2435,7 +2439,6 @@ bool WebRtcVideoMediaChannel::GetStats(const StatsOptions& options, WebRtcLocalStreamInfo* channel_stream_info = send_channel->local_stream_info(); - const StreamParams* send_params = send_channel->stream_params(); for (size_t i = 0; i < send_params->ssrcs.size(); ++i) { sinfo.add_ssrc(send_params->ssrcs[i]); } @@ -2720,8 +2723,7 @@ bool WebRtcVideoMediaChannel::SetCapturer(uint32 ssrc, } const int64 timestamp = send_channel->local_stream_info()->time_stamp(); if (send_codec_) { - QueueBlackFrame(ssrc, timestamp, - VideoFormat::FpsToInterval(send_codec_->maxFramerate)); + QueueBlackFrame(ssrc, timestamp, send_codec_->maxFramerate); } return true; } @@ -2743,7 +2745,7 @@ void WebRtcVideoMediaChannel::OnPacketReceived( int processing_channel_id = GetRecvChannelId(ssrc); if (processing_channel_id == kChannelIdUnset) { // Allocate an unsignalled recv channel for processing in conference mode. - if (!ConferenceModeIsEnabled()) { + if (!InConferenceMode()) { // If we can't find or allocate one, use the default. processing_channel_id = default_channel_id_; } else if (!CreateUnsignalledRecvChannel(ssrc, &processing_channel_id)) { @@ -3456,8 +3458,6 @@ bool WebRtcVideoMediaChannel::ConfigureSending(int channel_id, LOG_RTCERR2(ConnectCaptureDevice, vie_capture, channel_id); return false; } - - // Set up a new send channel. rtc::scoped_ptr send_channel( new WebRtcVideoChannelSendInfo(channel_id, vie_capture, external_capture, @@ -3549,7 +3549,7 @@ bool WebRtcVideoMediaChannel::SetNackFec(int channel_id, int fec_payload_type, bool nack_enabled) { bool enable = (red_payload_type != -1 && fec_payload_type != -1 && - !ConferenceModeIsEnabled()); + !InConferenceMode()); if (enable) { if (engine_->vie()->rtp()->SetHybridNACKFECStatus( channel_id, nack_enabled, red_payload_type, fec_payload_type) != 0) { @@ -3659,6 +3659,8 @@ bool WebRtcVideoMediaChannel::SetSendCodec( return false; } } + send_channel->set_interval( + cricket::VideoFormat::FpsToInterval(target_codec.maxFramerate)); return true; } @@ -3985,9 +3987,10 @@ void WebRtcVideoMediaChannel::SanitizeBitrates( } void WebRtcVideoMediaChannel::OnMessage(rtc::Message* msg) { - FlushBlackFrameData* data = static_cast(msg->pdata); - FlushBlackFrame(data->ssrc, data->timestamp, data->interval); - delete data; + FlushBlackFrameData* black_frame_data = + static_cast(msg->pdata); + FlushBlackFrame(black_frame_data->ssrc, black_frame_data->timestamp); + delete black_frame_data; } int WebRtcVideoMediaChannel::SendPacket(int channel, const void* data, @@ -4004,18 +4007,19 @@ int WebRtcVideoMediaChannel::SendRTCPPacket(int channel, } void WebRtcVideoMediaChannel::QueueBlackFrame(uint32 ssrc, int64 timestamp, - int interval) { + int framerate) { if (timestamp) { FlushBlackFrameData* black_frame_data = new FlushBlackFrameData( - ssrc, timestamp, interval); + ssrc, + timestamp); const int delay_ms = static_cast( - 2 * interval * rtc::kNumMillisecsPerSec / rtc::kNumNanosecsPerSec); + 2 * cricket::VideoFormat::FpsToInterval(framerate) * + rtc::kNumMillisecsPerSec / rtc::kNumNanosecsPerSec); worker_thread()->PostDelayed(delay_ms, this, 0, black_frame_data); } } -void WebRtcVideoMediaChannel::FlushBlackFrame( - uint32 ssrc, int64 timestamp, int interval) { +void WebRtcVideoMediaChannel::FlushBlackFrame(uint32 ssrc, int64 timestamp) { WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc); if (!send_channel) { return; @@ -4037,7 +4041,7 @@ void WebRtcVideoMediaChannel::FlushBlackFrame( WebRtcVideoFrame black_frame; // Black frame is not screencast. const bool screencasting = false; - const int64 timestamp_delta = interval; + const int64 timestamp_delta = send_channel->interval(); if (!black_frame.InitToBlack(send_codec_->width, send_codec_->height, 1, 1, last_frame_elapsed_time + timestamp_delta, last_frame_time_stamp + timestamp_delta) || @@ -4090,7 +4094,7 @@ bool WebRtcVideoMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, bool WebRtcVideoMediaChannel::SetPrimaryAndRtxSsrcs( int channel_id, int idx, uint32 primary_ssrc, - const StreamParams& sp) { + const StreamParams& send_params) { LOG(LS_INFO) << "Set primary ssrc " << primary_ssrc << " on channel " << channel_id << " idx " << idx; if (engine()->vie()->rtp()->SetLocalSSRC( @@ -4101,7 +4105,7 @@ bool WebRtcVideoMediaChannel::SetPrimaryAndRtxSsrcs( } uint32 rtx_ssrc = 0; - if (sp.GetFidSsrc(primary_ssrc, &rtx_ssrc)) { + if (send_params.GetFidSsrc(primary_ssrc, &rtx_ssrc)) { LOG(LS_INFO) << "Set rtx ssrc " << rtx_ssrc << " on channel " << channel_id << " idx " << idx; if (engine()->vie()->rtp()->SetLocalSSRC( diff --git a/talk/media/webrtc/webrtcvideoengine.h b/talk/media/webrtc/webrtcvideoengine.h index 55a3f0fac..72ba9df75 100644 --- a/talk/media/webrtc/webrtcvideoengine.h +++ b/talk/media/webrtc/webrtcvideoengine.h @@ -316,10 +316,6 @@ class WebRtcVideoMediaChannel : public rtc::MessageHandler, virtual int SendPacket(int channel, const void* data, int len) OVERRIDE; virtual int SendRTCPPacket(int channel, const void* data, int len) OVERRIDE; - bool ConferenceModeIsEnabled() const { - return options_.conference_mode.GetWithDefaultIfUnset(false); - } - // Checks the current bitrate estimate and modifies the bitrates // accordingly, including converting kAutoBandwidth to the correct defaults. virtual void SanitizeBitrates( @@ -391,7 +387,7 @@ class WebRtcVideoMediaChannel : public rtc::MessageHandler, bool SendIntraFrame(int channel_id); bool HasReadySendChannels(); - bool DefaultSendChannelIsActive(); + bool DefaultSendChannelInUse(); // Returns the ssrc key corresponding to the provided local SSRC in // |ssrc_key|. The return value is true upon success. If the local @@ -424,8 +420,8 @@ class WebRtcVideoMediaChannel : public rtc::MessageHandler, bool RemoveCapturer(uint32 ssrc); rtc::MessageQueue* worker_thread() { return engine_->worker_thread(); } - void QueueBlackFrame(uint32 ssrc, int64 timestamp, int interval); - void FlushBlackFrame(uint32 ssrc, int64 timestamp, int interval); + void QueueBlackFrame(uint32 ssrc, int64 timestamp, int framerate); + void FlushBlackFrame(uint32 ssrc, int64 timestamp); void SetNetworkTransmissionState(bool is_transmitting); diff --git a/talk/media/webrtc/webrtcvideoengine_unittest.cc b/talk/media/webrtc/webrtcvideoengine_unittest.cc index 00d6e4b1e..4060493de 100644 --- a/talk/media/webrtc/webrtcvideoengine_unittest.cc +++ b/talk/media/webrtc/webrtcvideoengine_unittest.cc @@ -1475,7 +1475,7 @@ TEST_F(WebRtcVideoEngineTestFake, SetStartBandwidthOption) { kMaxBandwidthKbps, kMinBandwidthKbps, kStartBandwidthKbps); // Set the start bitrate option. - unsigned int kBoostedStartBandwidthKbps = 1000; + int kBoostedStartBandwidthKbps = 1000; ASSERT_NE(kStartBandwidthKbps, kBoostedStartBandwidthKbps); cricket::VideoOptions options; options.video_start_bitrate.Set(kBoostedStartBandwidthKbps);