blob: 5673a5a321f7870c99652418f13496c311b58ac3 [file] [log] [blame]
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/video_engine/vie_channel_group.h"
#include "webrtc/common.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/utility/interface/process_thread.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/video_engine/call_stats.h"
#include "webrtc/video_engine/encoder_state_feedback.h"
#include "webrtc/video_engine/vie_channel.h"
#include "webrtc/video_engine/vie_encoder.h"
#include "webrtc/video_engine/vie_remb.h"
namespace webrtc {
namespace {
class WrappingBitrateEstimator : public RemoteBitrateEstimator {
public:
WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock,
ProcessThread* process_thread)
: observer_(observer),
clock_(clock),
process_thread_(process_thread),
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
rbe_(RemoteBitrateEstimatorFactory().Create(observer_, clock_)),
receive_absolute_send_time_(false) {
assert(process_thread_ != NULL);
process_thread_->RegisterModule(rbe_.get());
}
virtual ~WrappingBitrateEstimator() {
process_thread_->DeRegisterModule(rbe_.get());
}
void SetReceiveAbsoluteSendTimeStatus(bool enable) {
CriticalSectionScoped cs(crit_sect_.get());
if (enable == receive_absolute_send_time_) {
return;
}
process_thread_->DeRegisterModule(rbe_.get());
if (enable) {
rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create(
observer_, clock_));
} else {
rbe_.reset(RemoteBitrateEstimatorFactory().Create(observer_, clock_));
}
process_thread_->RegisterModule(rbe_.get());
receive_absolute_send_time_ = enable;
}
virtual void IncomingPacket(int64_t arrival_time_ms,
int payload_size,
const RTPHeader& header) {
CriticalSectionScoped cs(crit_sect_.get());
rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
}
virtual int32_t Process() {
assert(false && "Not supposed to register the WrappingBitrateEstimator!");
return 0;
}
virtual int32_t TimeUntilNextProcess() {
assert(false && "Not supposed to register the WrappingBitrateEstimator!");
return 0;
}
virtual void OnRttUpdate(uint32_t rtt) {
CriticalSectionScoped cs(crit_sect_.get());
rbe_->OnRttUpdate(rtt);
}
virtual void RemoveStream(unsigned int ssrc) {
CriticalSectionScoped cs(crit_sect_.get());
rbe_->RemoveStream(ssrc);
}
virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
unsigned int* bitrate_bps) const {
CriticalSectionScoped cs(crit_sect_.get());
return rbe_->LatestEstimate(ssrcs, bitrate_bps);
}
private:
RemoteBitrateObserver* observer_;
Clock* clock_;
ProcessThread* process_thread_;
scoped_ptr<CriticalSectionWrapper> crit_sect_;
scoped_ptr<RemoteBitrateEstimator> rbe_;
bool receive_absolute_send_time_;
DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
};
} // namespace
ChannelGroup::ChannelGroup(ProcessThread* process_thread,
const Config& config)
: remb_(new VieRemb()),
bitrate_controller_(BitrateController::CreateBitrateController()),
call_stats_(new CallStats()),
remote_bitrate_estimator_(new WrappingBitrateEstimator(remb_.get(),
Clock::GetRealTimeClock(), process_thread)),
encoder_state_feedback_(new EncoderStateFeedback()),
process_thread_(process_thread) {
call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get());
process_thread->RegisterModule(call_stats_.get());
}
ChannelGroup::~ChannelGroup() {
call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get());
process_thread_->DeRegisterModule(call_stats_.get());
assert(channels_.empty());
assert(!remb_->InUse());
}
void ChannelGroup::AddChannel(int channel_id) {
channels_.insert(channel_id);
}
void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) {
channels_.erase(channel_id);
remote_bitrate_estimator_->RemoveStream(ssrc);
}
bool ChannelGroup::HasChannel(int channel_id) {
return channels_.find(channel_id) != channels_.end();
}
bool ChannelGroup::Empty() {
return channels_.empty();
}
BitrateController* ChannelGroup::GetBitrateController() {
return bitrate_controller_.get();
}
RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() {
return remote_bitrate_estimator_.get();
}
CallStats* ChannelGroup::GetCallStats() {
return call_stats_.get();
}
EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
return encoder_state_feedback_.get();
}
bool ChannelGroup::SetChannelRembStatus(int channel_id, bool sender,
bool receiver, ViEChannel* channel) {
// Update the channel state.
if (sender || receiver) {
if (!channel->EnableRemb(true)) {
return false;
}
} else {
channel->EnableRemb(false);
}
// Update the REMB instance with necessary RTP modules.
RtpRtcp* rtp_module = channel->rtp_rtcp();
if (sender) {
remb_->AddRembSender(rtp_module);
} else {
remb_->RemoveRembSender(rtp_module);
}
if (receiver) {
remb_->AddReceiveChannel(rtp_module);
} else {
remb_->RemoveReceiveChannel(rtp_module);
}
return true;
}
void ChannelGroup::SetReceiveAbsoluteSendTimeStatus(bool enable) {
static_cast<WrappingBitrateEstimator*>(remote_bitrate_estimator_.get())->
SetReceiveAbsoluteSendTimeStatus(enable);
}
} // namespace webrtc