summaryrefslogtreecommitdiff
path: root/media/webrtc/webrtcvideoengine.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/webrtc/webrtcvideoengine.cc')
-rw-r--r--media/webrtc/webrtcvideoengine.cc348
1 files changed, 191 insertions, 157 deletions
diff --git a/media/webrtc/webrtcvideoengine.cc b/media/webrtc/webrtcvideoengine.cc
index 83b1177..b2533b3 100644
--- a/media/webrtc/webrtcvideoengine.cc
+++ b/media/webrtc/webrtcvideoengine.cc
@@ -64,6 +64,22 @@
#include "webrtc/experiments.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
+namespace {
+
+template <class T>
+bool Changed(cricket::Settable<T> proposed,
+ cricket::Settable<T> original) {
+ return proposed.IsSet() && proposed != original;
+}
+
+template <class T>
+bool Changed(cricket::Settable<T> proposed,
+ cricket::Settable<T> original,
+ T* value) {
+ return proposed.Get(value) && proposed != original;
+}
+
+} // namespace
namespace cricket {
@@ -81,6 +97,9 @@ const int kMaxVideoBitrate = 2000;
const int kCpuMonitorPeriodMs = 2000; // 2 seconds.
+// TODO(pthatcher): Figure out what the proper value here is, or if we
+// can just remove this altogether.
+static const int kDefaultRenderDelayMs = 100;
static const int kDefaultLogSeverity = rtc::LS_WARNING;
@@ -926,8 +945,6 @@ void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper,
initialized_ = false;
SetTraceFilter(SeverityToFilter(kDefaultLogSeverity));
render_module_.reset(new WebRtcPassthroughRender());
- local_renderer_w_ = local_renderer_h_ = 0;
- local_renderer_ = NULL;
capture_started_ = false;
decoder_factory_ = NULL;
encoder_factory_ = NULL;
@@ -953,6 +970,9 @@ void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper,
LOG(LS_ERROR) << "Failed to initialize list of supported codec types";
}
+ // Consider jitter, packet loss, etc when rendering. This will
+ // theoretically make rendering more smooth.
+ EnableTimedRender();
// Load our RTP Header extensions.
rtp_header_extensions_.push_back(
@@ -1059,10 +1079,6 @@ int WebRtcVideoEngine::GetCapabilities() {
return VIDEO_RECV | VIDEO_SEND;
}
-bool WebRtcVideoEngine::SetOptions(const VideoOptions &options) {
- return true;
-}
-
bool WebRtcVideoEngine::SetDefaultEncoderConfig(
const VideoEncoderConfig& config) {
return SetDefaultCodec(config.max_codec);
@@ -1109,12 +1125,6 @@ WebRtcVideoMediaChannel* WebRtcVideoEngine::CreateChannel(
return channel;
}
-bool WebRtcVideoEngine::SetLocalRenderer(VideoRenderer* renderer) {
- local_renderer_w_ = local_renderer_h_ = 0;
- local_renderer_ = renderer;
- return true;
-}
-
const std::vector<VideoCodec>& WebRtcVideoEngine::codecs() const {
return video_codecs_;
}
@@ -1568,6 +1578,7 @@ WebRtcVideoMediaChannel::WebRtcVideoMediaChannel(
remb_enabled_(false),
render_started_(false),
first_receive_ssrc_(kSsrcUnset),
+ receiver_report_ssrc_(kSsrcUnset),
num_unsignalled_recv_channels_(0),
send_rtx_type_(-1),
send_red_type_(-1),
@@ -1580,7 +1591,19 @@ WebRtcVideoMediaChannel::WebRtcVideoMediaChannel(
bool WebRtcVideoMediaChannel::Init() {
const uint32 ssrc_key = 0;
- return CreateChannel(ssrc_key, MD_SENDRECV, &default_channel_id_);
+ bool result = CreateChannel(ssrc_key, MD_SENDRECV, &default_channel_id_);
+ if (!result) {
+ return false;
+ }
+ if (voice_channel_) {
+ WebRtcVoiceMediaChannel* voice_channel =
+ static_cast<WebRtcVoiceMediaChannel*>(voice_channel_);
+ if (!voice_channel->SetupSharedBandwidthEstimation(
+ engine()->vie()->engine(), default_channel_id_)) {
+ return false;
+ }
+ }
+ return true;
}
WebRtcVideoMediaChannel::~WebRtcVideoMediaChannel() {
@@ -1752,6 +1775,35 @@ bool WebRtcVideoMediaChannel::SetSendCodecs(
return true;
}
+bool WebRtcVideoMediaChannel::MaybeRegisterExternalEncoder(
+ WebRtcVideoChannelSendInfo* send_channel,
+ 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)) {
+ return true;
+ }
+
+ webrtc::VideoEncoder* encoder =
+ engine()->CreateExternalEncoder(codec.codecType);
+ if (!encoder) {
+ // No encoder factor, so nothing to do.
+ return true;
+ }
+
+ const int channel_id = send_channel->channel_id();
+ if (engine()->vie()->ext_codec()->RegisterExternalSendCodec(
+ channel_id, codec.plType, encoder, false) != 0) {
+ LOG_RTCERR2(RegisterExternalSendCodec, channel_id, codec.plName);
+ engine()->DestroyExternalEncoder(encoder);
+ return false;
+ }
+
+ send_channel->RegisterEncoder(codec.plType, encoder);
+ return true;
+}
+
bool WebRtcVideoMediaChannel::GetSendCodec(VideoCodec* send_codec) {
if (!send_codec_) {
return false;
@@ -1861,18 +1913,9 @@ bool WebRtcVideoMediaChannel::AddSendStream(const StreamParams& sp) {
}
WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrcKey(ssrc_key);
- // Set the send (local) SSRC.
// If there are multiple send SSRCs, we can only set the first one here, and
// the rest of the SSRC(s) need to be set after SetSendCodec has been called
- // (with a codec requires multiple SSRC(s)).
- if (engine()->vie()->rtp()->SetLocalSSRC(channel_id,
- sp.first_ssrc()) != 0) {
- LOG_RTCERR2(SetLocalSSRC, channel_id, sp.first_ssrc());
- return false;
- }
-
- // Set the corresponding RTX SSRC.
- if (!SetLocalRtxSsrc(channel_id, sp, sp.first_ssrc(), 0)) {
+ if (!SetLimitedNumberOfSendSsrcs(channel_id, sp, 1)) {
return false;
}
@@ -1883,21 +1926,9 @@ bool WebRtcVideoMediaChannel::AddSendStream(const StreamParams& sp) {
return false;
}
- // At this point the channel's local SSRC has been updated. If the channel is
- // the default channel make sure that all the receive channels are updated as
- // well. Receive channels have to have the same SSRC as the default channel in
- // order to send receiver reports with this SSRC.
+ // Use the SSRC of the default channel in the RTCP receiver reports.
if (IsDefaultChannelId(channel_id)) {
- for (RecvChannelMap::const_iterator it = recv_channels_.begin();
- it != recv_channels_.end(); ++it) {
- WebRtcVideoChannelRecvInfo* info = it->second;
- int channel_id = info->channel_id();
- if (engine()->vie()->rtp()->SetLocalSSRC(channel_id,
- sp.first_ssrc()) != 0) {
- LOG_RTCERR1(SetLocalSSRC, it->first);
- return false;
- }
- }
+ SetReceiverReportSsrc(sp.first_ssrc());
}
send_channel->set_stream_params(sp);
@@ -2018,25 +2049,6 @@ bool WebRtcVideoMediaChannel::AddRecvStream(const StreamParams& sp) {
return false;
}
- // Get the default renderer.
- VideoRenderer* default_renderer = NULL;
- if (InConferenceMode()) {
- // The recv_channels_ size start out being 1, so if it is two here
- // this is the first receive channel created (default_channel_id_
- // is not used for receiving in a conference call). This means
- // that the renderer stored inside default_channel_id_ should be
- // used for the just created channel.
- if (recv_channels_.size() == 2 && GetDefaultRecvChannel()) {
- GetDefaultRenderer(&default_renderer);
- }
- }
-
- // The first recv stream reuses the default renderer (if a default renderer
- // has been set).
- if (default_renderer) {
- SetRenderer(sp.first_ssrc(), default_renderer);
- }
-
LOG(LS_INFO) << "New video stream " << sp.first_ssrc()
<< " registered to VideoEngine channel #"
<< channel_id << " and connected to channel #"
@@ -2228,6 +2240,9 @@ bool WebRtcVideoMediaChannel::GetSendChannelSsrcKey(uint32 local_ssrc,
return true;
}
if (!GetSendChannelBySsrcKey(local_ssrc)) {
+ // If a stream has multiple ssrcs, the local_ssrc could be any of
+ // them, but we use the first one (StreamParams::first_ssrc()) as
+ // the key.
for (SendChannelMap::iterator iter = send_channels_.begin();
iter != send_channels_.end(); ++iter) {
WebRtcVideoChannelSendInfo* send_channel = iter->second;
@@ -2898,7 +2913,7 @@ bool WebRtcVideoMediaChannel::SetStartSendBandwidth(int bps) {
}
// On success, SetSendCodec() will reset |send_start_bitrate_| to |bps/1000|,
- // by calling MaybeChangeBitrates. That method will also clamp the
+ // by calling SanitizeBitrates. That method will also clamp the
// start bitrate between min and max, consistent with the override behavior
// in SetMaxSendBandwidth.
webrtc::VideoCodec new_codec = *send_codec_;
@@ -2934,39 +2949,10 @@ bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) {
return true;
}
- // Trigger SetSendCodec to set correct noise reduction state if the option has
- // changed.
- bool denoiser_changed = options.video_noise_reduction.IsSet() &&
- (options_.video_noise_reduction != options.video_noise_reduction);
-
- bool leaky_bucket_changed = options.video_leaky_bucket.IsSet() &&
- (options_.video_leaky_bucket != options.video_leaky_bucket);
-
- bool buffer_latency_changed = options.buffered_mode_latency.IsSet() &&
- (options_.buffered_mode_latency != options.buffered_mode_latency);
-
- bool dscp_option_changed = (options_.dscp != options.dscp);
-
- bool suspend_below_min_bitrate_changed =
- options.suspend_below_min_bitrate.IsSet() &&
- (options_.suspend_below_min_bitrate != options.suspend_below_min_bitrate);
-
- bool conference_mode_turned_off = false;
- if (options_.conference_mode.IsSet() && options.conference_mode.IsSet() &&
- options_.conference_mode.GetWithDefaultIfUnset(false) &&
- !options.conference_mode.GetWithDefaultIfUnset(false)) {
- conference_mode_turned_off = true;
- }
-
-#ifdef USE_WEBRTC_DEV_BRANCH
- bool payload_padding_changed = options.use_payload_padding.IsSet() &&
- options_.use_payload_padding != options.use_payload_padding;
-#endif
-
-
// Save the options, to be interpreted where appropriate.
// Use options_.SetAll() instead of assignment so that unset value in options
// will not overwrite the previous option value.
+ VideoOptions original = options_;
options_.SetAll(options);
// Set CPU options for all send channels.
@@ -2977,38 +2963,36 @@ bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) {
}
if (send_codec_) {
- bool reset_send_codec_needed = denoiser_changed;
webrtc::VideoCodec new_codec = *send_codec_;
+ bool conference_mode_turned_off = (
+ original.conference_mode.IsSet() &&
+ options.conference_mode.IsSet() &&
+ original.conference_mode.GetWithDefaultIfUnset(false) &&
+ !options.conference_mode.GetWithDefaultIfUnset(false));
if (conference_mode_turned_off) {
// This is a special case for turning conference mode off.
// Max bitrate should go back to the default maximum value instead
// of the current maximum.
new_codec.maxBitrate = kAutoBandwidth;
- reset_send_codec_needed = true;
}
// TODO(pthatcher): Remove this. We don't need 4 ways to set bitrates.
int new_start_bitrate;
if (options.video_start_bitrate.Get(&new_start_bitrate)) {
new_codec.startBitrate = new_start_bitrate;
- reset_send_codec_needed = true;
}
-
- LOG(LS_INFO) << "Reset send codec needed is enabled? "
- << reset_send_codec_needed;
- if (reset_send_codec_needed) {
- if (!SetSendCodec(new_codec)) {
- return false;
- }
- LogSendCodecChange("SetOptions()");
+ if (!SetSendCodec(new_codec)) {
+ return false;
}
+ LogSendCodecChange("SetOptions()");
}
- if (leaky_bucket_changed) {
- bool enable_leaky_bucket =
- options_.video_leaky_bucket.GetWithDefaultIfUnset(true);
+ bool enable_leaky_bucket;
+ if (Changed(options.video_leaky_bucket,
+ original.video_leaky_bucket,
+ &enable_leaky_bucket)) {
LOG(LS_INFO) << "Leaky bucket is enabled? " << enable_leaky_bucket;
for (SendChannelMap::iterator it = send_channels_.begin();
it != send_channels_.end(); ++it) {
@@ -3022,10 +3006,11 @@ bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) {
}
}
}
- if (buffer_latency_changed) {
- int buffer_latency =
- options_.buffered_mode_latency.GetWithDefaultIfUnset(
- cricket::kBufferedModeDisabled);
+
+ int buffer_latency;
+ if (Changed(options.buffered_mode_latency,
+ original.buffered_mode_latency,
+ &buffer_latency)) {
LOG(LS_INFO) << "Buffer latency is " << buffer_latency;
for (SendChannelMap::iterator it = send_channels_.begin();
it != send_channels_.end(); ++it) {
@@ -3044,17 +3029,24 @@ bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) {
}
}
}
- if (dscp_option_changed) {
+
+ bool dscp_enabled;
+ if (Changed(options.dscp, original.dscp, &dscp_enabled)) {
rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT;
- if (options_.dscp.GetWithDefaultIfUnset(false))
+ if (dscp_enabled) {
dscp = kVideoDscpValue;
+ }
LOG(LS_INFO) << "DSCP is " << dscp;
if (MediaChannel::SetDscp(dscp) != 0) {
LOG(LS_WARNING) << "Failed to set DSCP settings for video channel";
}
}
- if (suspend_below_min_bitrate_changed) {
- if (options_.suspend_below_min_bitrate.GetWithDefaultIfUnset(false)) {
+
+ bool suspend_below_min_bitrate;
+ if (Changed(options.suspend_below_min_bitrate,
+ original.suspend_below_min_bitrate,
+ &suspend_below_min_bitrate)) {
+ if (suspend_below_min_bitrate) {
LOG(LS_INFO) << "Suspend below min bitrate enabled.";
for (SendChannelMap::iterator it = send_channels_.begin();
it != send_channels_.end(); ++it) {
@@ -3065,14 +3057,17 @@ bool WebRtcVideoMediaChannel::SetOptions(const VideoOptions &options) {
LOG(LS_WARNING) << "Cannot disable video suspension once it is enabled";
}
}
+
#ifdef USE_WEBRTC_DEV_BRANCH
- if (payload_padding_changed) {
+ bool use_payload_padding;
+ if (Changed(options.use_payload_padding,
+ original.use_payload_padding,
+ &use_payload_padding)) {
LOG(LS_INFO) << "Payload-based padding called.";
for (SendChannelMap::iterator it = send_channels_.begin();
it != send_channels_.end(); ++it) {
engine()->vie()->rtp()->SetPadWithRedundantPayloads(
- it->second->channel_id(),
- options_.use_payload_padding.GetWithDefaultIfUnset(false));
+ it->second->channel_id(), use_payload_padding);
}
}
#endif
@@ -3139,10 +3134,6 @@ bool WebRtcVideoMediaChannel::GetRenderer(uint32 ssrc,
return true;
}
-bool WebRtcVideoMediaChannel::GetDefaultRenderer(VideoRenderer** renderer) {
- return GetRenderer(kDefaultChannelSsrcKey, renderer);
-}
-
bool WebRtcVideoMediaChannel::GetVideoAdapter(
uint32 ssrc, CoordinatedVideoAdapter** video_adapter) {
WebRtcVideoChannelSendInfo* send_channel = GetSendChannelBySsrc(ssrc);
@@ -3413,6 +3404,11 @@ bool WebRtcVideoMediaChannel::ConfigureReceiving(int channel_id,
return false;
}
+ if (engine()->vie()->render()->SetExpectedRenderDelay(
+ channel_id, kDefaultRenderDelayMs)) {
+ LOG_RTCERR2(SetExpectedRenderDelay,
+ channel_id, kDefaultRenderDelayMs);
+ }
if (engine_->vie()->rtp()->SetRembStatus(channel_id,
kNotSending,
@@ -3431,20 +3427,13 @@ bool WebRtcVideoMediaChannel::ConfigureReceiving(int channel_id,
return false;
}
- if (remote_ssrc != kDefaultChannelSsrcKey) {
- // Use the same SSRC as our default channel
- // (so the RTCP reports are correct).
- unsigned int send_ssrc = 0;
- webrtc::ViERTP_RTCP* rtp = engine()->vie()->rtp();
- if (rtp->GetLocalSSRC(default_channel_id_, send_ssrc) == -1) {
- LOG_RTCERR2(GetLocalSSRC, default_channel_id_, send_ssrc);
- return false;
- }
- if (rtp->SetLocalSSRC(channel_id, send_ssrc) == -1) {
- LOG_RTCERR2(SetLocalSSRC, channel_id, send_ssrc);
+ if (receiver_report_ssrc_ != kSsrcUnset) {
+ if (engine()->vie()->rtp()->SetLocalSSRC(
+ channel_id, receiver_report_ssrc_) == -1) {
+ LOG_RTCERR2(SetLocalSSRC, channel_id, receiver_report_ssrc_);
return false;
}
- } // Else this is the the default channel and we don't change the SSRC.
+ }
// Disable color enhancement since it is a bit too aggressive.
if (engine()->vie()->image()->EnableColorEnhancement(channel_id,
@@ -3673,21 +3662,7 @@ bool WebRtcVideoMediaChannel::SetSendCodec(
target_codec.codecSpecific.VP8.denoisingOn = enable_denoising;
}
- // Register external encoder if codec type is supported by encoder factory.
- if (engine()->IsExternalEncoderCodecType(codec.codecType) &&
- !send_channel->IsEncoderRegistered(target_codec.plType)) {
- webrtc::VideoEncoder* encoder =
- engine()->CreateExternalEncoder(codec.codecType);
- if (encoder) {
- if (engine()->vie()->ext_codec()->RegisterExternalSendCodec(
- channel_id, target_codec.plType, encoder, false) == 0) {
- send_channel->RegisterEncoder(target_codec.plType, encoder);
- } else {
- LOG_RTCERR2(RegisterExternalSendCodec, channel_id, target_codec.plName);
- engine()->DestroyExternalEncoder(encoder);
- }
- }
- }
+ MaybeRegisterExternalEncoder(send_channel, target_codec);
// Resolution and framerate may vary for different send channels.
const VideoFormat& video_format = send_channel->video_format();
@@ -3698,7 +3673,8 @@ bool WebRtcVideoMediaChannel::SetSendCodec(
LOG(LS_INFO) << "0x0 resolution selected. Captured frames will be dropped "
<< "for ssrc: " << ssrc << ".";
} else {
- MaybeChangeBitrates(channel_id, &target_codec);
+ StreamParams* send_params = send_channel->stream_params();
+ SanitizeBitrates(channel_id, &target_codec);
webrtc::VideoCodec current_codec;
if (!engine()->vie()->codec()->GetSendCodec(channel_id, current_codec)) {
// Compare against existing configured send codec.
@@ -3713,6 +3689,11 @@ bool WebRtcVideoMediaChannel::SetSendCodec(
return false;
}
+ if (send_params) {
+ if (!SetSendSsrcs(channel_id, *send_params, target_codec)) {
+ return false;
+ }
+ }
// NOTE: SetRtxSendPayloadType must be called after all simulcast SSRCs
// are configured. Otherwise ssrc's configured after this point will use
// the primary PT for RTX.
@@ -3956,6 +3937,7 @@ bool WebRtcVideoMediaChannel::MaybeResetVieSendCodec(
int screencast_min_bitrate =
options_.screencast_min_bitrate.GetWithDefaultIfUnset(0);
bool leaky_bucket = options_.video_leaky_bucket.GetWithDefaultIfUnset(true);
+ StreamParams* send_params = send_channel->stream_params();
bool reset_send_codec =
target_width != cur_width || target_height != cur_height;
if (vie_codec.codecType == webrtc::kVideoCodecVP8) {
@@ -3979,7 +3961,7 @@ bool WebRtcVideoMediaChannel::MaybeResetVieSendCodec(
vie_codec.codecSpecific.VP8.denoisingOn = enable_denoising;
vie_codec.codecSpecific.VP8.frameDroppingOn = vp8_frame_dropping;
}
- MaybeChangeBitrates(channel_id, &vie_codec);
+ SanitizeBitrates(channel_id, &vie_codec);
if (engine()->vie()->codec()->SetSendCodec(channel_id, vie_codec) != 0) {
LOG_RTCERR1(SetSendCodec, channel_id);
@@ -4001,6 +3983,13 @@ bool WebRtcVideoMediaChannel::MaybeResetVieSendCodec(
engine()->vie()->rtp()->SetTransmissionSmoothingStatus(channel_id,
leaky_bucket);
}
+ // TODO(sriniv): SetSendCodec already sets ssrc's like below.
+ // Consider removing.
+ if (send_params) {
+ if (!SetSendSsrcs(channel_id, *send_params, target_codec)) {
+ return false;
+ }
+ }
if (reset) {
*reset = true;
}
@@ -4010,7 +3999,7 @@ bool WebRtcVideoMediaChannel::MaybeResetVieSendCodec(
return true;
}
-void WebRtcVideoMediaChannel::MaybeChangeBitrates(
+void WebRtcVideoMediaChannel::SanitizeBitrates(
int channel_id, webrtc::VideoCodec* codec) {
codec->minBitrate = GetBitrate(codec->minBitrate, kMinVideoBitrate);
codec->startBitrate = GetBitrate(codec->startBitrate, kStartVideoBitrate);
@@ -4047,7 +4036,6 @@ void WebRtcVideoMediaChannel::MaybeChangeBitrates(
codec->startBitrate = current_target_bitrate;
}
}
-
}
void WebRtcVideoMediaChannel::OnMessage(rtc::Message* msg) {
@@ -4156,21 +4144,55 @@ bool WebRtcVideoMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter,
return SetHeaderExtension(setter, channel_id, extension);
}
-bool WebRtcVideoMediaChannel::SetLocalRtxSsrc(int channel_id,
- const StreamParams& send_params,
- uint32 primary_ssrc,
- int stream_idx) {
- uint32 rtx_ssrc = 0;
- bool has_rtx = send_params.GetFidSsrc(primary_ssrc, &rtx_ssrc);
- if (has_rtx && engine()->vie()->rtp()->SetLocalSSRC(
- channel_id, rtx_ssrc, webrtc::kViEStreamTypeRtx, stream_idx) != 0) {
- LOG_RTCERR4(SetLocalSSRC, channel_id, rtx_ssrc,
- webrtc::kViEStreamTypeRtx, stream_idx);
+bool WebRtcVideoMediaChannel::SetPrimaryAndRtxSsrcs(
+ int channel_id, int idx, uint32 primary_ssrc,
+ const StreamParams& send_params) {
+ LOG(LS_INFO) << "Set primary ssrc " << primary_ssrc
+ << " on channel " << channel_id << " idx " << idx;
+ if (engine()->vie()->rtp()->SetLocalSSRC(
+ channel_id, primary_ssrc, webrtc::kViEStreamTypeNormal, idx) != 0) {
+ LOG_RTCERR4(SetLocalSSRC,
+ channel_id, primary_ssrc, webrtc::kViEStreamTypeNormal, idx);
return false;
}
+
+ uint32 rtx_ssrc = 0;
+ 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(
+ channel_id, rtx_ssrc, webrtc::kViEStreamTypeRtx, idx) != 0) {
+ LOG_RTCERR4(SetLocalSSRC,
+ channel_id, rtx_ssrc, webrtc::kViEStreamTypeRtx, idx);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebRtcVideoMediaChannel::SetLimitedNumberOfSendSsrcs(
+ int channel_id, const StreamParams& sp, size_t limit) {
+ const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics);
+ if (!sim_group || limit == 1) {
+ return SetPrimaryAndRtxSsrcs(channel_id, 0, sp.first_ssrc(), sp);
+ }
+
+ std::vector<uint32> ssrcs = sim_group->ssrcs;
+ for (size_t i = 0; i < ssrcs.size() && i < limit; ++i) {
+ if (!SetPrimaryAndRtxSsrcs(channel_id, static_cast<int>(i), ssrcs[i], sp)) {
+ return false;
+ }
+ }
return true;
}
+bool WebRtcVideoMediaChannel::SetSendSsrcs(
+ int channel_id, const StreamParams& sp,
+ const webrtc::VideoCodec& codec) {
+ // TODO(pthatcher): Support more than one primary SSRC per stream.
+ return SetLimitedNumberOfSendSsrcs(channel_id, sp, 1);
+}
+
void WebRtcVideoMediaChannel::MaybeConnectCapturer(VideoCapturer* capturer) {
if (capturer && GetSendChannelNum(capturer) == 1) {
capturer->SignalVideoFrame.connect(this,
@@ -4184,6 +4206,18 @@ void WebRtcVideoMediaChannel::MaybeDisconnectCapturer(VideoCapturer* capturer) {
}
}
+void WebRtcVideoMediaChannel::SetReceiverReportSsrc(uint32 ssrc) {
+ for (RecvChannelMap::const_iterator it = recv_channels_.begin();
+ it != recv_channels_.end(); ++it) {
+ int channel_id = it->second->channel_id();
+ if (engine()->vie()->rtp()->SetLocalSSRC(channel_id, ssrc) != 0) {
+ LOG_RTCERR2(SetLocalSSRC, channel_id, ssrc);
+ ASSERT(false);
+ }
+ }
+ receiver_report_ssrc_ = ssrc;
+}
+
} // namespace cricket
#endif // HAVE_WEBRTC_VIDEO