Hooking up EncoderStateFeedback to handle intra requests instead of trigger
ViEEncoder directly. This is one step towards adding send- and receive only
channels and getting rid of the default module.
BUG=769
Review URL: https://webrtc-codereview.appspot.com/824004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@2812 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
index 7399dc1..6dbf52c 100644
--- a/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
+++ b/src/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
@@ -225,6 +225,8 @@
virtual void OnReceivedRPSI(uint32_t ssrc,
uint64_t picture_id) = 0;
+ virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) = 0;
+
virtual ~RtcpIntraFrameObserver() {}
};
diff --git a/src/modules/rtp_rtcp/source/rtcp_receiver.cc b/src/modules/rtp_rtcp/source/rtcp_receiver.cc
index 631cc1b..c734e0c 100644
--- a/src/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/src/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -133,9 +133,19 @@
}
-void RTCPReceiver::SetSSRC( const WebRtc_UWord32 ssrc) {
+void RTCPReceiver::SetSSRC(const WebRtc_UWord32 ssrc) {
+ WebRtc_UWord32 old_ssrc = 0;
+ {
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
+ old_ssrc = _SSRC;
_SSRC = ssrc;
+ }
+ {
+ CriticalSectionScoped lock(_criticalSectionFeedbacks);
+ if (_cbRtcpIntraFrameObserver && old_ssrc != ssrc) {
+ _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, ssrc);
+ }
+ }
}
WebRtc_Word32 RTCPReceiver::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
@@ -1196,6 +1206,12 @@
// Might trigger a OnReceivedBandwidthEstimateUpdate.
UpdateTMMBR();
}
+ unsigned int local_ssrc = 0;
+ {
+ // We don't want to hold this critsect when triggering the callbacks below.
+ CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
+ local_ssrc = _SSRC;
+ }
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
_rtpRtcp.OnRequestSendReport();
}
@@ -1228,18 +1244,15 @@
"SIG [RTCP] Incoming FIR from SSRC:0x%x",
rtcpPacketInformation.remoteSSRC);
}
- _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(
- rtcpPacketInformation.remoteSSRC);
+ _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
}
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
_cbRtcpIntraFrameObserver->OnReceivedSLI(
- rtcpPacketInformation.remoteSSRC,
- rtcpPacketInformation.sliPictureId);
+ local_ssrc, rtcpPacketInformation.sliPictureId);
}
if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
_cbRtcpIntraFrameObserver->OnReceivedRPSI(
- rtcpPacketInformation.remoteSSRC,
- rtcpPacketInformation.rpsiPictureId);
+ local_ssrc, rtcpPacketInformation.rpsiPictureId);
}
}
if (_cbRtcpBandwidthObserver) {
diff --git a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 6002979..9716f8a 100644
--- a/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/src/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -106,6 +106,7 @@
// make sure that RTCP objects are aware of our SSRC
WebRtc_UWord32 SSRC = _rtpSender.SSRC();
_rtcpSender.SetSSRC(SSRC);
+ _rtcpReceiver.SetSSRC(SSRC);
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s created", __FUNCTION__);
}
diff --git a/src/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/src/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index ce77953..833f867 100644
--- a/src/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/src/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -71,6 +71,7 @@
uint64_t pictureId) {
EXPECT_EQ(kTestPictureId, pictureId);
};
+ virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {};
private:
RtpRtcp* _rtpRtcpModule;
};
diff --git a/src/video_engine/encoder_state_feedback.cc b/src/video_engine/encoder_state_feedback.cc
index cd155a6..64e32e2 100644
--- a/src/video_engine/encoder_state_feedback.cc
+++ b/src/video_engine/encoder_state_feedback.cc
@@ -37,6 +37,10 @@
owner_->OnReceivedRPSI(ssrc, picture_id);
}
+ virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {
+ owner_->OnLocalSsrcChanged(old_ssrc, new_ssrc);
+ }
+
private:
EncoderStateFeedback* owner_;
};
@@ -51,8 +55,10 @@
bool EncoderStateFeedback::AddEncoder(uint32_t ssrc, ViEEncoder* encoder) {
CriticalSectionScoped lock(crit_.get());
- if (encoders_.find(ssrc) != encoders_.end())
+ if (encoders_.find(ssrc) != encoders_.end()) {
+ // Two encoders must not have the same ssrc.
return false;
+ }
encoders_[ssrc] = encoder;
return true;
@@ -98,4 +104,16 @@
it->second->OnReceivedRPSI(ssrc, picture_id);
}
+void EncoderStateFeedback::OnLocalSsrcChanged(uint32_t old_ssrc,
+ uint32_t new_ssrc) {
+ CriticalSectionScoped lock(crit_.get());
+ SsrcEncoderMap::iterator it = encoders_.find(old_ssrc);
+ if (it == encoders_.end() || encoders_.find(new_ssrc) != encoders_.end()) {
+ return;
+ }
+
+ encoders_[new_ssrc] = it->second;
+ encoders_.erase(it);
+}
+
} // namespace webrtc
diff --git a/src/video_engine/encoder_state_feedback.h b/src/video_engine/encoder_state_feedback.h
index 7d063d4..45db92f 100644
--- a/src/video_engine/encoder_state_feedback.h
+++ b/src/video_engine/encoder_state_feedback.h
@@ -49,6 +49,7 @@
void OnReceivedIntraFrameRequest(uint32_t ssrc);
void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id);
void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id);
+ void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc);
private:
typedef std::map<uint32_t, ViEEncoder*> SsrcEncoderMap;
diff --git a/src/video_engine/encoder_state_feedback_unittest.cc b/src/video_engine/encoder_state_feedback_unittest.cc
index 3059526..07d1663 100644
--- a/src/video_engine/encoder_state_feedback_unittest.cc
+++ b/src/video_engine/encoder_state_feedback_unittest.cc
@@ -45,6 +45,8 @@
void(uint32_t ssrc, uint8_t picture_id));
MOCK_METHOD2(OnReceivedRPSI,
void(uint32_t ssrc, uint64_t picture_id));
+ MOCK_METHOD2(OnLocalSsrcChanged,
+ void(uint32_t old_ssrc, uint32_t new_ssrc));
};
class VieKeyRequestTest : public ::testing::Test {
diff --git a/src/video_engine/vie_channel_group.cc b/src/video_engine/vie_channel_group.cc
index 6254c21..d9830de 100644
--- a/src/video_engine/vie_channel_group.cc
+++ b/src/video_engine/vie_channel_group.cc
@@ -13,6 +13,7 @@
#include "modules/bitrate_controller/include/bitrate_controller.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "video_engine/encoder_state_feedback.h"
#include "video_engine/vie_channel.h"
#include "video_engine/vie_encoder.h"
#include "video_engine/vie_remb.h"
@@ -25,7 +26,8 @@
: remb_(new VieRemb(process_thread)),
bitrate_controller_(BitrateController::CreateBitrateController()),
remote_bitrate_estimator_(RemoteBitrateEstimator::Create(remb_.get(),
- options, mode)) {
+ options, mode)),
+ encoder_state_feedback_(new EncoderStateFeedback()) {
}
ChannelGroup::~ChannelGroup() {
@@ -57,6 +59,10 @@
return remote_bitrate_estimator_.get();
}
+EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() {
+ return encoder_state_feedback_.get();
+}
+
bool ChannelGroup::SetChannelRembStatus(int channel_id,
bool sender,
bool receiver,
diff --git a/src/video_engine/vie_channel_group.h b/src/video_engine/vie_channel_group.h
index 14b55db..4b6e927 100644
--- a/src/video_engine/vie_channel_group.h
+++ b/src/video_engine/vie_channel_group.h
@@ -19,6 +19,7 @@
namespace webrtc {
class BitrateController;
+class EncoderStateFeedback;
struct OverUseDetectorOptions;
class ProcessThread;
class ViEChannel;
@@ -47,6 +48,7 @@
BitrateController* GetBitrateController();
RemoteBitrateEstimator* GetRemoteBitrateEstimator();
+ EncoderStateFeedback* GetEncoderStateFeedback();
private:
typedef std::set<int> ChannelSet;
@@ -54,6 +56,7 @@
scoped_ptr<VieRemb> remb_;
scoped_ptr<BitrateController> bitrate_controller_;
scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
+ scoped_ptr<EncoderStateFeedback> encoder_state_feedback_;
ChannelSet channels_;
};
diff --git a/src/video_engine/vie_channel_manager.cc b/src/video_engine/vie_channel_manager.cc
index bb4d09f..fe0964b 100644
--- a/src/video_engine/vie_channel_manager.cc
+++ b/src/video_engine/vie_channel_manager.cc
@@ -16,6 +16,7 @@
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/map_wrapper.h"
#include "system_wrappers/interface/trace.h"
+#include "video_engine/encoder_state_feedback.h"
#include "video_engine/vie_channel.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_encoder.h"
@@ -103,10 +104,14 @@
bitrate_controller->CreateRtcpBandwidthObserver();
RemoteBitrateEstimator* remote_bitrate_estimator =
group->GetRemoteBitrateEstimator();
+ EncoderStateFeedback* encoder_state_feedback =
+ group->GetEncoderStateFeedback();
if (!(vie_encoder->Init() &&
CreateChannelObject(new_channel_id, vie_encoder, bandwidth_observer,
- remote_bitrate_estimator, true))) {
+ remote_bitrate_estimator,
+ encoder_state_feedback->GetRtcpIntraFrameObserver(),
+ true))) {
delete vie_encoder;
vie_encoder = NULL;
ReturnChannelId(new_channel_id);
@@ -114,6 +119,11 @@
return -1;
}
+ // Add ViEEncoder to EncoderFeedBackObserver.
+ unsigned int ssrc = 0;
+ channel_map_[new_channel_id]->GetLocalSSRC(&ssrc);
+ encoder_state_feedback->AddEncoder(ssrc, vie_encoder);
+
*channel_id = new_channel_id;
group->AddChannel(*channel_id);
channel_groups_.push_back(group);
@@ -141,6 +151,8 @@
bitrate_controller->CreateRtcpBandwidthObserver();
RemoteBitrateEstimator* remote_bitrate_estimator =
channel_group->GetRemoteBitrateEstimator();
+ EncoderStateFeedback* encoder_state_feedback =
+ channel_group->GetEncoderStateFeedback();
ViEEncoder* vie_encoder = NULL;
if (sender) {
@@ -149,18 +161,24 @@
*module_process_thread_,
bitrate_controller);
if (!(vie_encoder->Init() &&
- CreateChannelObject(new_channel_id, vie_encoder,
- bandwidth_observer,
- remote_bitrate_estimator,
- sender))) {
+ CreateChannelObject(
+ new_channel_id, vie_encoder, bandwidth_observer,
+ remote_bitrate_estimator,
+ encoder_state_feedback->GetRtcpIntraFrameObserver(), sender))) {
delete vie_encoder;
vie_encoder = NULL;
}
+ // Register the ViEEncoder to get key frame requests for this channel.
+ unsigned int ssrc = 0;
+ channel_map_[new_channel_id]->GetLocalSSRC(&ssrc);
+ encoder_state_feedback->AddEncoder(ssrc, vie_encoder);
} else {
vie_encoder = ViEEncoderPtr(original_channel);
assert(vie_encoder);
- if (!CreateChannelObject(new_channel_id, vie_encoder, bandwidth_observer,
- remote_bitrate_estimator, sender)) {
+ if (!CreateChannelObject(
+ new_channel_id, vie_encoder, bandwidth_observer,
+ remote_bitrate_estimator,
+ encoder_state_feedback->GetRtcpIntraFrameObserver(), sender)) {
vie_encoder = NULL;
}
}
@@ -206,9 +224,13 @@
group = FindGroup(channel_id);
group->SetChannelRembStatus(channel_id, false, false, vie_channel,
vie_encoder);
- unsigned int ssrc = 0;
- vie_channel->GetRemoteSSRC(&ssrc);
- group->RemoveChannel(channel_id, ssrc);
+ unsigned int remote_ssrc = 0;
+ vie_channel->GetRemoteSSRC(&remote_ssrc);
+ group->RemoveChannel(channel_id, remote_ssrc);
+
+ unsigned int local_ssrc = 0;
+ vie_channel->GetLocalSSRC(&local_ssrc);
+ group->GetEncoderStateFeedback()->RemoveEncoder(local_ssrc);
// Check if other channels are using the same encoder.
if (ChannelUsingViEEncoder(channel_id)) {
@@ -353,6 +375,7 @@
ViEEncoder* vie_encoder,
RtcpBandwidthObserver* bandwidth_observer,
RemoteBitrateEstimator* remote_bitrate_estimator,
+ RtcpIntraFrameObserver* intra_frame_observer,
bool sender) {
// Register the channel at the encoder.
RtpRtcp* send_rtp_rtcp_module = vie_encoder->SendRtpRtcpModule();
@@ -360,7 +383,7 @@
ViEChannel* vie_channel = new ViEChannel(channel_id, engine_id_,
number_of_cores_,
*module_process_thread_,
- vie_encoder,
+ intra_frame_observer,
bandwidth_observer,
remote_bitrate_estimator,
send_rtp_rtcp_module,
diff --git a/src/video_engine/vie_channel_manager.h b/src/video_engine/vie_channel_manager.h
index 758cdd3..2409751 100644
--- a/src/video_engine/vie_channel_manager.h
+++ b/src/video_engine/vie_channel_manager.h
@@ -85,6 +85,7 @@
bool CreateChannelObject(int channel_id, ViEEncoder* vie_encoder,
RtcpBandwidthObserver* bandwidth_observer,
RemoteBitrateEstimator* remote_bitrate_estimator,
+ RtcpIntraFrameObserver* intra_frame_observer,
bool sender);
// Used by ViEChannelScoped, forcing a manager user to use scoped.
diff --git a/src/video_engine/vie_encoder.cc b/src/video_engine/vie_encoder.cc
index e56b6b3..054ff0f 100644
--- a/src/video_engine/vie_encoder.cc
+++ b/src/video_engine/vie_encoder.cc
@@ -822,6 +822,9 @@
time_last_intra_request_ms_ = now;
}
+void ViEEncoder::OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {
+}
+
// Called from ViEBitrateObserver.
void ViEEncoder::OnNetworkChanged(const uint32_t bitrate_bps,
const uint8_t fraction_lost,
diff --git a/src/video_engine/vie_encoder.h b/src/video_engine/vie_encoder.h
index 475c232..d68706c 100644
--- a/src/video_engine/vie_encoder.h
+++ b/src/video_engine/vie_encoder.h
@@ -130,12 +130,9 @@
// Implements RtcpIntraFrameObserver.
virtual void OnReceivedIntraFrameRequest(uint32_t ssrc);
-
- virtual void OnReceivedSLI(uint32_t ssrc,
- uint8_t picture_id);
-
- virtual void OnReceivedRPSI(uint32_t ssrc,
- uint64_t picture_id);
+ virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id);
+ virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id);
+ virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc);
// Effect filter.
WebRtc_Word32 RegisterEffectFilter(ViEEffectFilter* effect_filter);