aboutsummaryrefslogtreecommitdiff
path: root/webrtc/video_engine
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/video_engine')
-rw-r--r--webrtc/video_engine/OWNERS13
-rw-r--r--webrtc/video_engine/call_stats.cc167
-rw-r--r--webrtc/video_engine/call_stats.h81
-rw-r--r--webrtc/video_engine/call_stats_unittest.cc203
-rw-r--r--webrtc/video_engine/encoder_state_feedback.cc124
-rw-r--r--webrtc/video_engine/encoder_state_feedback.h71
-rw-r--r--webrtc/video_engine/encoder_state_feedback_unittest.cc143
-rw-r--r--webrtc/video_engine/overuse_frame_detector.cc422
-rw-r--r--webrtc/video_engine/overuse_frame_detector.h181
-rw-r--r--webrtc/video_engine/overuse_frame_detector_unittest.cc405
-rw-r--r--webrtc/video_engine/payload_router.cc101
-rw-r--r--webrtc/video_engine/payload_router.h85
-rw-r--r--webrtc/video_engine/payload_router_unittest.cc209
-rw-r--r--webrtc/video_engine/report_block_stats.cc111
-rw-r--r--webrtc/video_engine/report_block_stats.h62
-rw-r--r--webrtc/video_engine/report_block_stats_unittest.cc146
-rw-r--r--webrtc/video_engine/stream_synchronization.cc226
-rw-r--r--webrtc/video_engine/stream_synchronization.h59
-rw-r--r--webrtc/video_engine/stream_synchronization_unittest.cc562
-rw-r--r--webrtc/video_engine/video_engine_core_unittests.gyp74
-rw-r--r--webrtc/video_engine/video_engine_core_unittests.isolate23
-rw-r--r--webrtc/video_engine/vie_channel.cc1253
-rw-r--r--webrtc/video_engine/vie_channel.h458
-rw-r--r--webrtc/video_engine/vie_codec_unittest.cc230
-rw-r--r--webrtc/video_engine/vie_defines.h120
-rw-r--r--webrtc/video_engine/vie_encoder.cc710
-rw-r--r--webrtc/video_engine/vie_encoder.h201
-rw-r--r--webrtc/video_engine/vie_receiver.cc482
-rw-r--r--webrtc/video_engine/vie_receiver.h131
-rw-r--r--webrtc/video_engine/vie_remb.cc143
-rw-r--r--webrtc/video_engine/vie_remb.h78
-rw-r--r--webrtc/video_engine/vie_remb_unittest.cc251
-rw-r--r--webrtc/video_engine/vie_sync_module.cc188
-rw-r--r--webrtc/video_engine/vie_sync_module.h65
34 files changed, 0 insertions, 7778 deletions
diff --git a/webrtc/video_engine/OWNERS b/webrtc/video_engine/OWNERS
deleted file mode 100644
index a8201f0252..0000000000
--- a/webrtc/video_engine/OWNERS
+++ /dev/null
@@ -1,13 +0,0 @@
-mflodman@webrtc.org
-pbos@webrtc.org
-stefan@webrtc.org
-
-per-file *.isolate=kjellander@webrtc.org
-
-# These are for the common case of adding or renaming files. If you're doing
-# structural changes, please get a review from a reviewer in this file.
-per-file *.gyp=*
-per-file *.gypi=*
-
-per-file BUILD.gn=kjellander@webrtc.org
-
diff --git a/webrtc/video_engine/call_stats.cc b/webrtc/video_engine/call_stats.cc
deleted file mode 100644
index 0b71cc346c..0000000000
--- a/webrtc/video_engine/call_stats.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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/call_stats.h"
-
-#include <assert.h>
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-
-namespace webrtc {
-namespace {
-// Time interval for updating the observers.
-const int64_t kUpdateIntervalMs = 1000;
-// Weight factor to apply to the average rtt.
-const float kWeightFactor = 0.3f;
-
-void RemoveOldReports(int64_t now, std::list<CallStats::RttTime>* reports) {
- // A rtt report is considered valid for this long.
- const int64_t kRttTimeoutMs = 1500;
- while (!reports->empty() &&
- (now - reports->front().time) > kRttTimeoutMs) {
- reports->pop_front();
- }
-}
-
-int64_t GetMaxRttMs(std::list<CallStats::RttTime>* reports) {
- int64_t max_rtt_ms = 0;
- for (std::list<CallStats::RttTime>::const_iterator it = reports->begin();
- it != reports->end(); ++it) {
- max_rtt_ms = std::max(it->rtt, max_rtt_ms);
- }
- return max_rtt_ms;
-}
-
-int64_t GetAvgRttMs(std::list<CallStats::RttTime>* reports) {
- if (reports->empty()) {
- return 0;
- }
- int64_t sum = 0;
- for (std::list<CallStats::RttTime>::const_iterator it = reports->begin();
- it != reports->end(); ++it) {
- sum += it->rtt;
- }
- return sum / reports->size();
-}
-
-void UpdateAvgRttMs(std::list<CallStats::RttTime>* reports, int64_t* avg_rtt) {
- uint32_t cur_rtt_ms = GetAvgRttMs(reports);
- if (cur_rtt_ms == 0) {
- // Reset.
- *avg_rtt = 0;
- return;
- }
- if (*avg_rtt == 0) {
- // Initialize.
- *avg_rtt = cur_rtt_ms;
- return;
- }
- *avg_rtt = *avg_rtt * (1.0f - kWeightFactor) + cur_rtt_ms * kWeightFactor;
-}
-} // namespace
-
-class RtcpObserver : public RtcpRttStats {
- public:
- explicit RtcpObserver(CallStats* owner) : owner_(owner) {}
- virtual ~RtcpObserver() {}
-
- virtual void OnRttUpdate(int64_t rtt) {
- owner_->OnRttUpdate(rtt);
- }
-
- // Returns the average RTT.
- virtual int64_t LastProcessedRtt() const {
- return owner_->avg_rtt_ms();
- }
-
- private:
- CallStats* owner_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(RtcpObserver);
-};
-
-CallStats::CallStats()
- : crit_(CriticalSectionWrapper::CreateCriticalSection()),
- rtcp_rtt_stats_(new RtcpObserver(this)),
- last_process_time_(TickTime::MillisecondTimestamp()),
- max_rtt_ms_(0),
- avg_rtt_ms_(0) {
-}
-
-CallStats::~CallStats() {
- assert(observers_.empty());
-}
-
-int64_t CallStats::TimeUntilNextProcess() {
- return last_process_time_ + kUpdateIntervalMs -
- TickTime::MillisecondTimestamp();
-}
-
-int32_t CallStats::Process() {
- CriticalSectionScoped cs(crit_.get());
- int64_t now = TickTime::MillisecondTimestamp();
- if (now < last_process_time_ + kUpdateIntervalMs)
- return 0;
-
- last_process_time_ = now;
-
- RemoveOldReports(now, &reports_);
- max_rtt_ms_ = GetMaxRttMs(&reports_);
- UpdateAvgRttMs(&reports_, &avg_rtt_ms_);
-
- // If there is a valid rtt, update all observers with the max rtt.
- // TODO(asapersson): Consider changing this to report the average rtt.
- if (max_rtt_ms_ > 0) {
- for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
- it != observers_.end(); ++it) {
- (*it)->OnRttUpdate(avg_rtt_ms_, max_rtt_ms_);
- }
- }
- return 0;
-}
-
-int64_t CallStats::avg_rtt_ms() const {
- CriticalSectionScoped cs(crit_.get());
- return avg_rtt_ms_;
-}
-
-RtcpRttStats* CallStats::rtcp_rtt_stats() const {
- return rtcp_rtt_stats_.get();
-}
-
-void CallStats::RegisterStatsObserver(CallStatsObserver* observer) {
- CriticalSectionScoped cs(crit_.get());
- for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
- it != observers_.end(); ++it) {
- if (*it == observer)
- return;
- }
- observers_.push_back(observer);
-}
-
-void CallStats::DeregisterStatsObserver(CallStatsObserver* observer) {
- CriticalSectionScoped cs(crit_.get());
- for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
- it != observers_.end(); ++it) {
- if (*it == observer) {
- observers_.erase(it);
- return;
- }
- }
-}
-
-void CallStats::OnRttUpdate(int64_t rtt) {
- CriticalSectionScoped cs(crit_.get());
- reports_.push_back(RttTime(rtt, TickTime::MillisecondTimestamp()));
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/call_stats.h b/webrtc/video_engine/call_stats.h
deleted file mode 100644
index a17330a7c1..0000000000
--- a/webrtc/video_engine/call_stats.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_CALL_STATS_H_
-#define WEBRTC_VIDEO_ENGINE_CALL_STATS_H_
-
-#include <list>
-
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/interface/module.h"
-
-namespace webrtc {
-
-class CallStatsObserver;
-class CriticalSectionWrapper;
-class RtcpRttStats;
-
-// CallStats keeps track of statistics for a call.
-class CallStats : public Module {
- public:
- friend class RtcpObserver;
-
- CallStats();
- ~CallStats();
-
- // Implements Module, to use the process thread.
- int64_t TimeUntilNextProcess() override;
- int32_t Process() override;
-
- // Returns a RtcpRttStats to register at a statistics provider. The object
- // has the same lifetime as the CallStats instance.
- RtcpRttStats* rtcp_rtt_stats() const;
-
- // Registers/deregisters a new observer to receive statistics updates.
- void RegisterStatsObserver(CallStatsObserver* observer);
- void DeregisterStatsObserver(CallStatsObserver* observer);
-
- // Helper struct keeping track of the time a rtt value is reported.
- struct RttTime {
- RttTime(int64_t new_rtt, int64_t rtt_time)
- : rtt(new_rtt), time(rtt_time) {}
- const int64_t rtt;
- const int64_t time;
- };
-
- protected:
- void OnRttUpdate(int64_t rtt);
-
- int64_t avg_rtt_ms() const;
-
- private:
- // Protecting all members.
- rtc::scoped_ptr<CriticalSectionWrapper> crit_;
- // Observer receiving statistics updates.
- rtc::scoped_ptr<RtcpRttStats> rtcp_rtt_stats_;
- // The last time 'Process' resulted in statistic update.
- int64_t last_process_time_;
- // The last RTT in the statistics update (zero if there is no valid estimate).
- int64_t max_rtt_ms_;
- int64_t avg_rtt_ms_;
-
- // All Rtt reports within valid time interval, oldest first.
- std::list<RttTime> reports_;
-
- // Observers getting stats reports.
- std::list<CallStatsObserver*> observers_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(CallStats);
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_CALL_STATS_H_
diff --git a/webrtc/video_engine/call_stats_unittest.cc b/webrtc/video_engine/call_stats_unittest.cc
deleted file mode 100644
index 4fb88df338..0000000000
--- a/webrtc/video_engine/call_stats_unittest.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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 "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/video_engine/call_stats.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::Return;
-
-namespace webrtc {
-
-class MockStatsObserver : public CallStatsObserver {
- public:
- MockStatsObserver() {}
- virtual ~MockStatsObserver() {}
-
- MOCK_METHOD2(OnRttUpdate, void(int64_t, int64_t));
-};
-
-class CallStatsTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- TickTime::UseFakeClock(12345);
- call_stats_.reset(new CallStats());
- }
- rtc::scoped_ptr<CallStats> call_stats_;
-};
-
-TEST_F(CallStatsTest, AddAndTriggerCallback) {
- MockStatsObserver stats_observer;
- RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
- call_stats_->RegisterStatsObserver(&stats_observer);
- TickTime::AdvanceFakeClock(1000);
- EXPECT_EQ(0, rtcp_rtt_stats->LastProcessedRtt());
-
- const int64_t kRtt = 25;
- rtcp_rtt_stats->OnRttUpdate(kRtt);
- EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt)).Times(1);
- call_stats_->Process();
- EXPECT_EQ(kRtt, rtcp_rtt_stats->LastProcessedRtt());
-
- const int64_t kRttTimeOutMs = 1500 + 10;
- TickTime::AdvanceFakeClock(kRttTimeOutMs);
- EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
- call_stats_->Process();
- EXPECT_EQ(0, rtcp_rtt_stats->LastProcessedRtt());
-
- call_stats_->DeregisterStatsObserver(&stats_observer);
-}
-
-TEST_F(CallStatsTest, ProcessTime) {
- MockStatsObserver stats_observer;
- call_stats_->RegisterStatsObserver(&stats_observer);
- RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
- rtcp_rtt_stats->OnRttUpdate(100);
-
- // Time isn't updated yet.
- EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
- call_stats_->Process();
-
- // Advance clock and verify we get an update.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
- call_stats_->Process();
-
- // Advance clock just too little to get an update.
- TickTime::AdvanceFakeClock(999);
- rtcp_rtt_stats->OnRttUpdate(100);
- EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
- call_stats_->Process();
-
- // Advance enough to trigger a new update.
- TickTime::AdvanceFakeClock(1);
- EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
- call_stats_->Process();
-
- call_stats_->DeregisterStatsObserver(&stats_observer);
-}
-
-// Verify all observers get correct estimates and observers can be added and
-// removed.
-TEST_F(CallStatsTest, MultipleObservers) {
- MockStatsObserver stats_observer_1;
- call_stats_->RegisterStatsObserver(&stats_observer_1);
- // Add the second observer twice, there should still be only one report to the
- // observer.
- MockStatsObserver stats_observer_2;
- call_stats_->RegisterStatsObserver(&stats_observer_2);
- call_stats_->RegisterStatsObserver(&stats_observer_2);
-
- RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
- const int64_t kRtt = 100;
- rtcp_rtt_stats->OnRttUpdate(kRtt);
-
- // Verify both observers are updated.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
- EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(1);
- call_stats_->Process();
-
- // Deregister the second observer and verify update is only sent to the first
- // observer.
- call_stats_->DeregisterStatsObserver(&stats_observer_2);
- rtcp_rtt_stats->OnRttUpdate(kRtt);
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
- EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
- call_stats_->Process();
-
- // Deregister the first observer.
- call_stats_->DeregisterStatsObserver(&stats_observer_1);
- rtcp_rtt_stats->OnRttUpdate(kRtt);
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(0);
- EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
- call_stats_->Process();
-}
-
-// Verify increasing and decreasing rtt triggers callbacks with correct values.
-TEST_F(CallStatsTest, ChangeRtt) {
- MockStatsObserver stats_observer;
- call_stats_->RegisterStatsObserver(&stats_observer);
- RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
-
- // Advance clock to be ready for an update.
- TickTime::AdvanceFakeClock(1000);
-
- // Set a first value and verify the callback is triggered.
- const int64_t kFirstRtt = 100;
- rtcp_rtt_stats->OnRttUpdate(kFirstRtt);
- EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt, kFirstRtt)).Times(1);
- call_stats_->Process();
-
- // Increase rtt and verify the new value is reported.
- TickTime::AdvanceFakeClock(1000);
- const int64_t kHighRtt = kFirstRtt + 20;
- const int64_t kAvgRtt1 = 103;
- rtcp_rtt_stats->OnRttUpdate(kHighRtt);
- EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kHighRtt)).Times(1);
- call_stats_->Process();
-
- // Increase time enough for a new update, but not too much to make the
- // rtt invalid. Report a lower rtt and verify the old/high value still is sent
- // in the callback.
- TickTime::AdvanceFakeClock(1000);
- const int64_t kLowRtt = kFirstRtt - 20;
- const int64_t kAvgRtt2 = 102;
- rtcp_rtt_stats->OnRttUpdate(kLowRtt);
- EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kHighRtt)).Times(1);
- call_stats_->Process();
-
- // Advance time to make the high report invalid, the lower rtt should now be
- // in the callback.
- TickTime::AdvanceFakeClock(1000);
- const int64_t kAvgRtt3 = 95;
- EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt3, kLowRtt)).Times(1);
- call_stats_->Process();
-
- call_stats_->DeregisterStatsObserver(&stats_observer);
-}
-
-TEST_F(CallStatsTest, LastProcessedRtt) {
- MockStatsObserver stats_observer;
- call_stats_->RegisterStatsObserver(&stats_observer);
- RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
- TickTime::AdvanceFakeClock(1000);
-
- // Set a first values and verify that LastProcessedRtt initially returns the
- // average rtt.
- const int64_t kRttLow = 10;
- const int64_t kRttHigh = 30;
- const int64_t kAvgRtt = 20;
- rtcp_rtt_stats->OnRttUpdate(kRttLow);
- rtcp_rtt_stats->OnRttUpdate(kRttHigh);
- EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
- call_stats_->Process();
- EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
-
- // Update values and verify LastProcessedRtt.
- TickTime::AdvanceFakeClock(1000);
- rtcp_rtt_stats->OnRttUpdate(kRttLow);
- rtcp_rtt_stats->OnRttUpdate(kRttHigh);
- EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
- call_stats_->Process();
- EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
-
- call_stats_->DeregisterStatsObserver(&stats_observer);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/encoder_state_feedback.cc b/webrtc/video_engine/encoder_state_feedback.cc
deleted file mode 100644
index 1c376b2820..0000000000
--- a/webrtc/video_engine/encoder_state_feedback.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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/encoder_state_feedback.h"
-
-#include <assert.h>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/video_engine/vie_encoder.h"
-
-namespace webrtc {
-
-// Helper class registered at the RTP module relaying callbacks to
-// EncoderStatFeedback.
-class EncoderStateFeedbackObserver : public RtcpIntraFrameObserver {
- public:
- explicit EncoderStateFeedbackObserver(EncoderStateFeedback* owner)
- : owner_(owner) {}
- ~EncoderStateFeedbackObserver() {}
-
- // Implements RtcpIntraFrameObserver.
- virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
- owner_->OnReceivedIntraFrameRequest(ssrc);
- }
- virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
- owner_->OnReceivedSLI(ssrc, picture_id);
- }
- virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
- 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_;
-};
-
-EncoderStateFeedback::EncoderStateFeedback()
- : crit_(CriticalSectionWrapper::CreateCriticalSection()),
- observer_(new EncoderStateFeedbackObserver(this)) {}
-
-EncoderStateFeedback::~EncoderStateFeedback() {
- assert(encoders_.empty());
-}
-
-void EncoderStateFeedback::AddEncoder(const std::vector<uint32_t>& ssrcs,
- ViEEncoder* encoder) {
- RTC_DCHECK(!ssrcs.empty());
- CriticalSectionScoped lock(crit_.get());
- for (uint32_t ssrc : ssrcs) {
- RTC_DCHECK(encoders_.find(ssrc) == encoders_.end());
- encoders_[ssrc] = encoder;
- }
-}
-
-void EncoderStateFeedback::RemoveEncoder(const ViEEncoder* encoder) {
- CriticalSectionScoped lock(crit_.get());
- SsrcEncoderMap::iterator it = encoders_.begin();
- while (it != encoders_.end()) {
- if (it->second == encoder) {
- encoders_.erase(it++);
- } else {
- ++it;
- }
- }
-}
-
-RtcpIntraFrameObserver* EncoderStateFeedback::GetRtcpIntraFrameObserver() {
- return observer_.get();
-}
-
-void EncoderStateFeedback::OnReceivedIntraFrameRequest(uint32_t ssrc) {
- CriticalSectionScoped lock(crit_.get());
- SsrcEncoderMap::iterator it = encoders_.find(ssrc);
- if (it == encoders_.end())
- return;
-
- it->second->OnReceivedIntraFrameRequest(ssrc);
-}
-
-void EncoderStateFeedback::OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) {
- CriticalSectionScoped lock(crit_.get());
- SsrcEncoderMap::iterator it = encoders_.find(ssrc);
- if (it == encoders_.end())
- return;
-
- it->second->OnReceivedSLI(ssrc, picture_id);
-}
-
-void EncoderStateFeedback::OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) {
- CriticalSectionScoped lock(crit_.get());
- SsrcEncoderMap::iterator it = encoders_.find(ssrc);
- if (it == encoders_.end())
- return;
-
- 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;
- }
-
- ViEEncoder* encoder = it->second;
- encoders_.erase(it);
- encoders_[new_ssrc] = encoder;
- encoder->OnLocalSsrcChanged(old_ssrc, new_ssrc);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/encoder_state_feedback.h b/webrtc/video_engine/encoder_state_feedback.h
deleted file mode 100644
index 51e9111dfe..0000000000
--- a/webrtc/video_engine/encoder_state_feedback.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- */
-
-// TODO(mflodman) ViEEncoder has a time check to not send key frames too often,
-// move the logic to this class.
-
-#ifndef WEBRTC_VIDEO_ENGINE_ENCODER_STATE_FEEDBACK_H_
-#define WEBRTC_VIDEO_ENGINE_ENCODER_STATE_FEEDBACK_H_
-
-#include <map>
-#include <vector>
-
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-
-class CriticalSectionWrapper;
-class EncoderStateFeedbackObserver;
-class RtcpIntraFrameObserver;
-class ViEEncoder;
-
-class EncoderStateFeedback {
- public:
- friend class EncoderStateFeedbackObserver;
-
- EncoderStateFeedback();
- ~EncoderStateFeedback();
-
- // Adds an encoder to receive feedback for a set of SSRCs.
- void AddEncoder(const std::vector<uint32_t>& ssrc, ViEEncoder* encoder);
-
- // Removes a registered ViEEncoder.
- void RemoveEncoder(const ViEEncoder* encoder);
-
- // Returns an observer to register at the requesting class. The observer has
- // the same lifetime as the EncoderStateFeedback instance.
- RtcpIntraFrameObserver* GetRtcpIntraFrameObserver();
-
- protected:
- // Called by EncoderStateFeedbackObserver when a new key frame is requested.
- 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;
-
- rtc::scoped_ptr<CriticalSectionWrapper> crit_;
-
- // Instance registered at the class requesting new key frames.
- rtc::scoped_ptr<EncoderStateFeedbackObserver> observer_;
-
- // Maps a unique ssrc to the given encoder.
- SsrcEncoderMap encoders_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(EncoderStateFeedback);
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_ENCODER_STATE_FEEDBACK_H_
diff --git a/webrtc/video_engine/encoder_state_feedback_unittest.cc b/webrtc/video_engine/encoder_state_feedback_unittest.cc
deleted file mode 100644
index 9787acc144..0000000000
--- a/webrtc/video_engine/encoder_state_feedback_unittest.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.
- */
-
-
-// This file includes unit tests for EncoderStateFeedback.
-#include "webrtc/video_engine/encoder_state_feedback.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/common.h"
-#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
-#include "webrtc/modules/pacing/include/paced_sender.h"
-#include "webrtc/modules/pacing/include/packet_router.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/utility/interface/mock/mock_process_thread.h"
-#include "webrtc/video_engine/payload_router.h"
-#include "webrtc/video_engine/vie_encoder.h"
-
-using ::testing::NiceMock;
-
-namespace webrtc {
-
-class MockVieEncoder : public ViEEncoder {
- public:
- explicit MockVieEncoder(ProcessThread* process_thread, PacedSender* pacer)
- : ViEEncoder(1, process_thread, nullptr, nullptr, pacer, nullptr) {}
- ~MockVieEncoder() {}
-
- MOCK_METHOD1(OnReceivedIntraFrameRequest,
- void(uint32_t));
- MOCK_METHOD2(OnReceivedSLI,
- 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 {
- protected:
- VieKeyRequestTest()
- : pacer_(Clock::GetRealTimeClock(),
- &router_,
- BitrateController::kDefaultStartBitrateKbps,
- PacedSender::kDefaultPaceMultiplier *
- BitrateController::kDefaultStartBitrateKbps,
- 0) {}
- virtual void SetUp() {
- process_thread_.reset(new NiceMock<MockProcessThread>);
- encoder_state_feedback_.reset(new EncoderStateFeedback());
- }
- rtc::scoped_ptr<MockProcessThread> process_thread_;
- rtc::scoped_ptr<EncoderStateFeedback> encoder_state_feedback_;
- PacketRouter router_;
- PacedSender pacer_;
-};
-
-TEST_F(VieKeyRequestTest, CreateAndTriggerRequests) {
- const int ssrc = 1234;
- MockVieEncoder encoder(process_thread_.get(), &pacer_);
- encoder_state_feedback_->AddEncoder(std::vector<uint32_t>(1, ssrc), &encoder);
-
- EXPECT_CALL(encoder, OnReceivedIntraFrameRequest(ssrc))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->
- OnReceivedIntraFrameRequest(ssrc);
-
- const uint8_t sli_picture_id = 3;
- EXPECT_CALL(encoder, OnReceivedSLI(ssrc, sli_picture_id))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedSLI(
- ssrc, sli_picture_id);
-
- const uint64_t rpsi_picture_id = 9;
- EXPECT_CALL(encoder, OnReceivedRPSI(ssrc, rpsi_picture_id))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedRPSI(
- ssrc, rpsi_picture_id);
-
- encoder_state_feedback_->RemoveEncoder(&encoder);
-}
-
-// Register multiple encoders and make sure the request is relayed to correct
-// ViEEncoder.
-TEST_F(VieKeyRequestTest, MultipleEncoders) {
- const int ssrc_1 = 1234;
- const int ssrc_2 = 5678;
- MockVieEncoder encoder_1(process_thread_.get(), &pacer_);
- MockVieEncoder encoder_2(process_thread_.get(), &pacer_);
- encoder_state_feedback_->AddEncoder(std::vector<uint32_t>(1, ssrc_1),
- &encoder_1);
- encoder_state_feedback_->AddEncoder(std::vector<uint32_t>(1, ssrc_2),
- &encoder_2);
-
- EXPECT_CALL(encoder_1, OnReceivedIntraFrameRequest(ssrc_1))
- .Times(1);
- EXPECT_CALL(encoder_2, OnReceivedIntraFrameRequest(ssrc_2))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->
- OnReceivedIntraFrameRequest(ssrc_1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->
- OnReceivedIntraFrameRequest(ssrc_2);
-
- const uint8_t sli_pid_1 = 3;
- const uint8_t sli_pid_2 = 4;
- EXPECT_CALL(encoder_1, OnReceivedSLI(ssrc_1, sli_pid_1))
- .Times(1);
- EXPECT_CALL(encoder_2, OnReceivedSLI(ssrc_2, sli_pid_2))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedSLI(
- ssrc_1, sli_pid_1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedSLI(
- ssrc_2, sli_pid_2);
-
- const uint64_t rpsi_pid_1 = 9;
- const uint64_t rpsi_pid_2 = 10;
- EXPECT_CALL(encoder_1, OnReceivedRPSI(ssrc_1, rpsi_pid_1))
- .Times(1);
- EXPECT_CALL(encoder_2, OnReceivedRPSI(ssrc_2, rpsi_pid_2))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedRPSI(
- ssrc_1, rpsi_pid_1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedRPSI(
- ssrc_2, rpsi_pid_2);
-
- encoder_state_feedback_->RemoveEncoder(&encoder_1);
- EXPECT_CALL(encoder_2, OnReceivedIntraFrameRequest(ssrc_2))
- .Times(1);
- encoder_state_feedback_->GetRtcpIntraFrameObserver()->
- OnReceivedIntraFrameRequest(ssrc_2);
- encoder_state_feedback_->RemoveEncoder(&encoder_2);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/overuse_frame_detector.cc b/webrtc/video_engine/overuse_frame_detector.cc
deleted file mode 100644
index 47a6e496b9..0000000000
--- a/webrtc/video_engine/overuse_frame_detector.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (c) 2013 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/overuse_frame_detector.h"
-
-#include <assert.h>
-#include <math.h>
-
-#include <algorithm>
-#include <list>
-#include <map>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/base/exp_filter.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/system_wrappers/include/clock.h"
-
-namespace webrtc {
-
-namespace {
-const int64_t kProcessIntervalMs = 5000;
-
-// Delay between consecutive rampups. (Used for quick recovery.)
-const int kQuickRampUpDelayMs = 10 * 1000;
-// Delay between rampup attempts. Initially uses standard, scales up to max.
-const int kStandardRampUpDelayMs = 40 * 1000;
-const int kMaxRampUpDelayMs = 240 * 1000;
-// Expontential back-off factor, to prevent annoying up-down behaviour.
-const double kRampUpBackoffFactor = 2.0;
-
-// Max number of overuses detected before always applying the rampup delay.
-const int kMaxOverusesBeforeApplyRampupDelay = 4;
-
-// The maximum exponent to use in VCMExpFilter.
-const float kSampleDiffMs = 33.0f;
-const float kMaxExp = 7.0f;
-
-} // namespace
-
-// Class for calculating the average encode time.
-class OveruseFrameDetector::EncodeTimeAvg {
- public:
- EncodeTimeAvg()
- : kWeightFactor(0.5f),
- kInitialAvgEncodeTimeMs(5.0f),
- filtered_encode_time_ms_(new rtc::ExpFilter(kWeightFactor)) {
- filtered_encode_time_ms_->Apply(1.0f, kInitialAvgEncodeTimeMs);
- }
- ~EncodeTimeAvg() {}
-
- void AddSample(float encode_time_ms, int64_t diff_last_sample_ms) {
- float exp = diff_last_sample_ms / kSampleDiffMs;
- exp = std::min(exp, kMaxExp);
- filtered_encode_time_ms_->Apply(exp, encode_time_ms);
- }
-
- int Value() const {
- return static_cast<int>(filtered_encode_time_ms_->filtered() + 0.5);
- }
-
- private:
- const float kWeightFactor;
- const float kInitialAvgEncodeTimeMs;
- rtc::scoped_ptr<rtc::ExpFilter> filtered_encode_time_ms_;
-};
-
-// Class for calculating the processing usage on the send-side (the average
-// processing time of a frame divided by the average time difference between
-// captured frames).
-class OveruseFrameDetector::SendProcessingUsage {
- public:
- explicit SendProcessingUsage(const CpuOveruseOptions& options)
- : kWeightFactorFrameDiff(0.998f),
- kWeightFactorProcessing(0.995f),
- kInitialSampleDiffMs(40.0f),
- kMaxSampleDiffMs(45.0f),
- count_(0),
- options_(options),
- filtered_processing_ms_(new rtc::ExpFilter(kWeightFactorProcessing)),
- filtered_frame_diff_ms_(new rtc::ExpFilter(kWeightFactorFrameDiff)) {
- Reset();
- }
- ~SendProcessingUsage() {}
-
- void Reset() {
- count_ = 0;
- filtered_frame_diff_ms_->Reset(kWeightFactorFrameDiff);
- filtered_frame_diff_ms_->Apply(1.0f, kInitialSampleDiffMs);
- filtered_processing_ms_->Reset(kWeightFactorProcessing);
- filtered_processing_ms_->Apply(1.0f, InitialProcessingMs());
- }
-
- void AddCaptureSample(float sample_ms) {
- float exp = sample_ms / kSampleDiffMs;
- exp = std::min(exp, kMaxExp);
- filtered_frame_diff_ms_->Apply(exp, sample_ms);
- }
-
- void AddSample(float processing_ms, int64_t diff_last_sample_ms) {
- ++count_;
- float exp = diff_last_sample_ms / kSampleDiffMs;
- exp = std::min(exp, kMaxExp);
- filtered_processing_ms_->Apply(exp, processing_ms);
- }
-
- int Value() const {
- if (count_ < static_cast<uint32_t>(options_.min_frame_samples)) {
- return static_cast<int>(InitialUsageInPercent() + 0.5f);
- }
- float frame_diff_ms = std::max(filtered_frame_diff_ms_->filtered(), 1.0f);
- frame_diff_ms = std::min(frame_diff_ms, kMaxSampleDiffMs);
- float encode_usage_percent =
- 100.0f * filtered_processing_ms_->filtered() / frame_diff_ms;
- return static_cast<int>(encode_usage_percent + 0.5);
- }
-
- private:
- float InitialUsageInPercent() const {
- // Start in between the underuse and overuse threshold.
- return (options_.low_encode_usage_threshold_percent +
- options_.high_encode_usage_threshold_percent) / 2.0f;
- }
-
- float InitialProcessingMs() const {
- return InitialUsageInPercent() * kInitialSampleDiffMs / 100;
- }
-
- const float kWeightFactorFrameDiff;
- const float kWeightFactorProcessing;
- const float kInitialSampleDiffMs;
- const float kMaxSampleDiffMs;
- uint64_t count_;
- const CpuOveruseOptions options_;
- rtc::scoped_ptr<rtc::ExpFilter> filtered_processing_ms_;
- rtc::scoped_ptr<rtc::ExpFilter> filtered_frame_diff_ms_;
-};
-
-// Class for calculating the processing time of frames.
-class OveruseFrameDetector::FrameQueue {
- public:
- FrameQueue() : last_processing_time_ms_(-1) {}
- ~FrameQueue() {}
-
- // Called when a frame is captured.
- // Starts the measuring of the processing time of the frame.
- void Start(int64_t capture_time, int64_t now) {
- const size_t kMaxSize = 90; // Allows for processing time of 1.5s at 60fps.
- if (frame_times_.size() > kMaxSize) {
- LOG(LS_WARNING) << "Max size reached, removed oldest frame.";
- frame_times_.erase(frame_times_.begin());
- }
- if (frame_times_.find(capture_time) != frame_times_.end()) {
- // Frame should not exist.
- assert(false);
- return;
- }
- frame_times_[capture_time] = now;
- }
-
- // Called when the processing of a frame has finished.
- // Returns the processing time of the frame.
- int End(int64_t capture_time, int64_t now) {
- std::map<int64_t, int64_t>::iterator it = frame_times_.find(capture_time);
- if (it == frame_times_.end()) {
- return -1;
- }
- // Remove any old frames up to current.
- // Old frames have been skipped by the capture process thread.
- // TODO(asapersson): Consider measuring time from first frame in list.
- last_processing_time_ms_ = now - (*it).second;
- frame_times_.erase(frame_times_.begin(), ++it);
- return last_processing_time_ms_;
- }
-
- void Reset() { frame_times_.clear(); }
- int NumFrames() const { return static_cast<int>(frame_times_.size()); }
- int last_processing_time_ms() const { return last_processing_time_ms_; }
-
- private:
- // Captured frames mapped by the capture time.
- std::map<int64_t, int64_t> frame_times_;
- int last_processing_time_ms_;
-};
-
-
-OveruseFrameDetector::OveruseFrameDetector(
- Clock* clock,
- const CpuOveruseOptions& options,
- CpuOveruseObserver* observer,
- CpuOveruseMetricsObserver* metrics_observer)
- : options_(options),
- observer_(observer),
- metrics_observer_(metrics_observer),
- clock_(clock),
- num_process_times_(0),
- last_capture_time_(0),
- num_pixels_(0),
- next_process_time_(clock_->TimeInMilliseconds()),
- last_overuse_time_(0),
- checks_above_threshold_(0),
- num_overuse_detections_(0),
- last_rampup_time_(0),
- in_quick_rampup_(false),
- current_rampup_delay_ms_(kStandardRampUpDelayMs),
- last_encode_sample_ms_(0),
- last_sample_time_ms_(0),
- encode_time_(new EncodeTimeAvg()),
- usage_(new SendProcessingUsage(options)),
- frame_queue_(new FrameQueue()) {
- RTC_DCHECK(metrics_observer != nullptr);
- // Make sure stats are initially up-to-date. This simplifies unit testing
- // since we don't have to trigger an update using one of the methods which
- // would also alter the overuse state.
- UpdateCpuOveruseMetrics();
- processing_thread_.DetachFromThread();
-}
-
-OveruseFrameDetector::~OveruseFrameDetector() {
-}
-
-int OveruseFrameDetector::LastProcessingTimeMs() const {
- rtc::CritScope cs(&crit_);
- return frame_queue_->last_processing_time_ms();
-}
-
-int OveruseFrameDetector::FramesInQueue() const {
- rtc::CritScope cs(&crit_);
- return frame_queue_->NumFrames();
-}
-
-void OveruseFrameDetector::UpdateCpuOveruseMetrics() {
- metrics_.avg_encode_time_ms = encode_time_->Value();
- metrics_.encode_usage_percent = usage_->Value();
-
- metrics_observer_->CpuOveruseMetricsUpdated(metrics_);
-}
-
-int64_t OveruseFrameDetector::TimeUntilNextProcess() {
- RTC_DCHECK(processing_thread_.CalledOnValidThread());
- return next_process_time_ - clock_->TimeInMilliseconds();
-}
-
-bool OveruseFrameDetector::FrameSizeChanged(int num_pixels) const {
- if (num_pixels != num_pixels_) {
- return true;
- }
- return false;
-}
-
-bool OveruseFrameDetector::FrameTimeoutDetected(int64_t now) const {
- if (last_capture_time_ == 0) {
- return false;
- }
- return (now - last_capture_time_) > options_.frame_timeout_interval_ms;
-}
-
-void OveruseFrameDetector::ResetAll(int num_pixels) {
- num_pixels_ = num_pixels;
- usage_->Reset();
- frame_queue_->Reset();
- last_capture_time_ = 0;
- num_process_times_ = 0;
- UpdateCpuOveruseMetrics();
-}
-
-void OveruseFrameDetector::FrameCaptured(int width,
- int height,
- int64_t capture_time_ms) {
- rtc::CritScope cs(&crit_);
-
- int64_t now = clock_->TimeInMilliseconds();
- if (FrameSizeChanged(width * height) || FrameTimeoutDetected(now)) {
- ResetAll(width * height);
- }
-
- if (last_capture_time_ != 0)
- usage_->AddCaptureSample(now - last_capture_time_);
-
- last_capture_time_ = now;
-
- if (options_.enable_extended_processing_usage) {
- frame_queue_->Start(capture_time_ms, now);
- }
-}
-
-void OveruseFrameDetector::FrameEncoded(int encode_time_ms) {
- rtc::CritScope cs(&crit_);
- int64_t now = clock_->TimeInMilliseconds();
- if (last_encode_sample_ms_ != 0) {
- int64_t diff_ms = now - last_encode_sample_ms_;
- encode_time_->AddSample(encode_time_ms, diff_ms);
- }
- last_encode_sample_ms_ = now;
-
- if (!options_.enable_extended_processing_usage) {
- AddProcessingTime(encode_time_ms);
- }
- UpdateCpuOveruseMetrics();
-}
-
-void OveruseFrameDetector::FrameSent(int64_t capture_time_ms) {
- rtc::CritScope cs(&crit_);
- if (!options_.enable_extended_processing_usage) {
- return;
- }
- int delay_ms = frame_queue_->End(capture_time_ms,
- clock_->TimeInMilliseconds());
- if (delay_ms > 0) {
- AddProcessingTime(delay_ms);
- }
- UpdateCpuOveruseMetrics();
-}
-
-void OveruseFrameDetector::AddProcessingTime(int elapsed_ms) {
- int64_t now = clock_->TimeInMilliseconds();
- if (last_sample_time_ms_ != 0) {
- int64_t diff_ms = now - last_sample_time_ms_;
- usage_->AddSample(elapsed_ms, diff_ms);
- }
- last_sample_time_ms_ = now;
-}
-
-int32_t OveruseFrameDetector::Process() {
- RTC_DCHECK(processing_thread_.CalledOnValidThread());
-
- int64_t now = clock_->TimeInMilliseconds();
-
- // Used to protect against Process() being called too often.
- if (now < next_process_time_)
- return 0;
-
- next_process_time_ = now + kProcessIntervalMs;
-
- CpuOveruseMetrics current_metrics;
- {
- rtc::CritScope cs(&crit_);
- ++num_process_times_;
-
- current_metrics = metrics_;
- if (num_process_times_ <= options_.min_process_count)
- return 0;
- }
-
- if (IsOverusing(current_metrics)) {
- // If the last thing we did was going up, and now have to back down, we need
- // to check if this peak was short. If so we should back off to avoid going
- // back and forth between this load, the system doesn't seem to handle it.
- bool check_for_backoff = last_rampup_time_ > last_overuse_time_;
- if (check_for_backoff) {
- if (now - last_rampup_time_ < kStandardRampUpDelayMs ||
- num_overuse_detections_ > kMaxOverusesBeforeApplyRampupDelay) {
- // Going up was not ok for very long, back off.
- current_rampup_delay_ms_ *= kRampUpBackoffFactor;
- if (current_rampup_delay_ms_ > kMaxRampUpDelayMs)
- current_rampup_delay_ms_ = kMaxRampUpDelayMs;
- } else {
- // Not currently backing off, reset rampup delay.
- current_rampup_delay_ms_ = kStandardRampUpDelayMs;
- }
- }
-
- last_overuse_time_ = now;
- in_quick_rampup_ = false;
- checks_above_threshold_ = 0;
- ++num_overuse_detections_;
-
- if (observer_ != NULL)
- observer_->OveruseDetected();
- } else if (IsUnderusing(current_metrics, now)) {
- last_rampup_time_ = now;
- in_quick_rampup_ = true;
-
- if (observer_ != NULL)
- observer_->NormalUsage();
- }
-
- int rampup_delay =
- in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
-
- LOG(LS_VERBOSE) << " Frame stats: "
- << " encode usage " << current_metrics.encode_usage_percent
- << " overuse detections " << num_overuse_detections_
- << " rampup delay " << rampup_delay;
-
- return 0;
-}
-
-bool OveruseFrameDetector::IsOverusing(const CpuOveruseMetrics& metrics) {
- bool overusing = false;
- if (options_.enable_encode_usage_method) {
- overusing = metrics.encode_usage_percent >=
- options_.high_encode_usage_threshold_percent;
- }
- if (overusing) {
- ++checks_above_threshold_;
- } else {
- checks_above_threshold_ = 0;
- }
- return checks_above_threshold_ >= options_.high_threshold_consecutive_count;
-}
-
-bool OveruseFrameDetector::IsUnderusing(const CpuOveruseMetrics& metrics,
- int64_t time_now) {
- int delay = in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
- if (time_now < last_rampup_time_ + delay)
- return false;
-
- bool underusing = false;
- if (options_.enable_encode_usage_method) {
- underusing = metrics.encode_usage_percent <
- options_.low_encode_usage_threshold_percent;
- }
- return underusing;
-}
-} // namespace webrtc
diff --git a/webrtc/video_engine/overuse_frame_detector.h b/webrtc/video_engine/overuse_frame_detector.h
deleted file mode 100644
index aff4b43025..0000000000
--- a/webrtc/video_engine/overuse_frame_detector.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2013 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
-#define WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
-
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/base/criticalsection.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/exp_filter.h"
-#include "webrtc/base/thread_annotations.h"
-#include "webrtc/base/thread_checker.h"
-#include "webrtc/modules/interface/module.h"
-
-namespace webrtc {
-
-class Clock;
-
-// CpuOveruseObserver is called when a system overuse is detected and
-// VideoEngine cannot keep up the encoding frequency.
-class CpuOveruseObserver {
- public:
- // Called as soon as an overuse is detected.
- virtual void OveruseDetected() = 0;
- // Called periodically when the system is not overused any longer.
- virtual void NormalUsage() = 0;
-
- protected:
- virtual ~CpuOveruseObserver() {}
-};
-
-struct CpuOveruseOptions {
- CpuOveruseOptions()
- : enable_encode_usage_method(true),
- low_encode_usage_threshold_percent(55),
- high_encode_usage_threshold_percent(85),
- enable_extended_processing_usage(true),
- frame_timeout_interval_ms(1500),
- min_frame_samples(120),
- min_process_count(3),
- high_threshold_consecutive_count(2) {}
-
- // Method based on encode time of frames.
- bool enable_encode_usage_method;
- int low_encode_usage_threshold_percent; // Threshold for triggering underuse.
- int high_encode_usage_threshold_percent; // Threshold for triggering overuse.
- bool enable_extended_processing_usage; // Include a larger time span (in
- // addition to encode time) for
- // measuring the processing time of a
- // frame.
- // General settings.
- int frame_timeout_interval_ms; // The maximum allowed interval between two
- // frames before resetting estimations.
- int min_frame_samples; // The minimum number of frames required.
- int min_process_count; // The number of initial process times required before
- // triggering an overuse/underuse.
- int high_threshold_consecutive_count; // The number of consecutive checks
- // above the high threshold before
- // triggering an overuse.
-};
-
-struct CpuOveruseMetrics {
- CpuOveruseMetrics()
- : avg_encode_time_ms(-1),
- encode_usage_percent(-1) {}
-
- int avg_encode_time_ms; // The average encode time in ms.
- int encode_usage_percent; // The average encode time divided by the average
- // time difference between incoming captured frames.
-};
-
-class CpuOveruseMetricsObserver {
- public:
- virtual ~CpuOveruseMetricsObserver() {}
- virtual void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) = 0;
-};
-
-
-// Use to detect system overuse based on the send-side processing time of
-// incoming frames.
-class OveruseFrameDetector : public Module {
- public:
- OveruseFrameDetector(Clock* clock,
- const CpuOveruseOptions& options,
- CpuOveruseObserver* overuse_observer,
- CpuOveruseMetricsObserver* metrics_observer);
- ~OveruseFrameDetector();
-
- // Called for each captured frame.
- void FrameCaptured(int width, int height, int64_t capture_time_ms);
-
- // Called for each encoded frame.
- void FrameEncoded(int encode_time_ms);
-
- // Called for each sent frame.
- void FrameSent(int64_t capture_time_ms);
-
- // Only public for testing.
- int LastProcessingTimeMs() const;
- int FramesInQueue() const;
-
- // Implements Module.
- int64_t TimeUntilNextProcess() override;
- int32_t Process() override;
-
- private:
- class EncodeTimeAvg;
- class SendProcessingUsage;
- class FrameQueue;
-
- void UpdateCpuOveruseMetrics() EXCLUSIVE_LOCKS_REQUIRED(crit_);
-
- // TODO(asapersson): This method is only used on one thread, so it shouldn't
- // need a guard.
- void AddProcessingTime(int elapsed_ms) EXCLUSIVE_LOCKS_REQUIRED(crit_);
-
- // Only called on the processing thread.
- bool IsOverusing(const CpuOveruseMetrics& metrics);
- bool IsUnderusing(const CpuOveruseMetrics& metrics, int64_t time_now);
-
- bool FrameTimeoutDetected(int64_t now) const EXCLUSIVE_LOCKS_REQUIRED(crit_);
- bool FrameSizeChanged(int num_pixels) const EXCLUSIVE_LOCKS_REQUIRED(crit_);
-
- void ResetAll(int num_pixels) EXCLUSIVE_LOCKS_REQUIRED(crit_);
-
- // Protecting all members except const and those that are only accessed on the
- // processing thread.
- // TODO(asapersson): See if we can reduce locking. As is, video frame
- // processing contends with reading stats and the processing thread.
- mutable rtc::CriticalSection crit_;
-
- const CpuOveruseOptions options_;
-
- // Observer getting overuse reports.
- CpuOveruseObserver* const observer_;
-
- // Stats metrics.
- CpuOveruseMetricsObserver* const metrics_observer_;
- CpuOveruseMetrics metrics_ GUARDED_BY(crit_);
-
- Clock* const clock_;
- int64_t num_process_times_ GUARDED_BY(crit_);
-
- int64_t last_capture_time_ GUARDED_BY(crit_);
-
- // Number of pixels of last captured frame.
- int num_pixels_ GUARDED_BY(crit_);
-
- // These seven members are only accessed on the processing thread.
- int64_t next_process_time_;
- int64_t last_overuse_time_;
- int checks_above_threshold_;
- int num_overuse_detections_;
- int64_t last_rampup_time_;
- bool in_quick_rampup_;
- int current_rampup_delay_ms_;
-
- int64_t last_encode_sample_ms_; // Only accessed by one thread.
- int64_t last_sample_time_ms_; // Only accessed by one thread.
-
- // TODO(asapersson): Can these be regular members (avoid separate heap
- // allocs)?
- const rtc::scoped_ptr<EncodeTimeAvg> encode_time_ GUARDED_BY(crit_);
- const rtc::scoped_ptr<SendProcessingUsage> usage_ GUARDED_BY(crit_);
- const rtc::scoped_ptr<FrameQueue> frame_queue_ GUARDED_BY(crit_);
-
- rtc::ThreadChecker processing_thread_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector);
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_
diff --git a/webrtc/video_engine/overuse_frame_detector_unittest.cc b/webrtc/video_engine/overuse_frame_detector_unittest.cc
deleted file mode 100644
index d502f02204..0000000000
--- a/webrtc/video_engine/overuse_frame_detector_unittest.cc
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright (c) 2013 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/overuse_frame_detector.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/system_wrappers/include/clock.h"
-
-namespace webrtc {
-namespace {
- const int kWidth = 640;
- const int kHeight = 480;
- const int kFrameInterval33ms = 33;
- const int kProcessIntervalMs = 5000;
- const int kProcessTime5ms = 5;
-} // namespace
-
-class MockCpuOveruseObserver : public CpuOveruseObserver {
- public:
- MockCpuOveruseObserver() {}
- virtual ~MockCpuOveruseObserver() {}
-
- MOCK_METHOD0(OveruseDetected, void());
- MOCK_METHOD0(NormalUsage, void());
-};
-
-class CpuOveruseObserverImpl : public CpuOveruseObserver {
- public:
- CpuOveruseObserverImpl() :
- overuse_(0),
- normaluse_(0) {}
- virtual ~CpuOveruseObserverImpl() {}
-
- void OveruseDetected() { ++overuse_; }
- void NormalUsage() { ++normaluse_; }
-
- int overuse_;
- int normaluse_;
-};
-
-class OveruseFrameDetectorTest : public ::testing::Test,
- public CpuOveruseMetricsObserver {
- protected:
- virtual void SetUp() {
- clock_.reset(new SimulatedClock(1234));
- observer_.reset(new MockCpuOveruseObserver());
- options_.min_process_count = 0;
- ReinitializeOveruseDetector();
- }
-
- void ReinitializeOveruseDetector() {
- overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_,
- observer_.get(), this));
- }
-
- void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override {
- metrics_ = metrics;
- }
-
- int InitialUsage() {
- return ((options_.low_encode_usage_threshold_percent +
- options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5;
- }
-
- void InsertAndSendFramesWithInterval(
- int num_frames, int interval_ms, int width, int height, int delay_ms) {
- while (num_frames-- > 0) {
- int64_t capture_time_ms = clock_->TimeInMilliseconds();
- overuse_detector_->FrameCaptured(width, height, capture_time_ms);
- clock_->AdvanceTimeMilliseconds(delay_ms);
- overuse_detector_->FrameEncoded(delay_ms);
- overuse_detector_->FrameSent(capture_time_ms);
- clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms);
- }
- }
-
- void TriggerOveruse(int num_times) {
- const int kDelayMs = 32;
- for (int i = 0; i < num_times; ++i) {
- InsertAndSendFramesWithInterval(
- 1000, kFrameInterval33ms, kWidth, kHeight, kDelayMs);
- overuse_detector_->Process();
- }
- }
-
- void TriggerUnderuse() {
- const int kDelayMs1 = 5;
- const int kDelayMs2 = 6;
- InsertAndSendFramesWithInterval(
- 1300, kFrameInterval33ms, kWidth, kHeight, kDelayMs1);
- InsertAndSendFramesWithInterval(
- 1, kFrameInterval33ms, kWidth, kHeight, kDelayMs2);
- overuse_detector_->Process();
- }
-
- int AvgEncodeTimeMs() { return metrics_.avg_encode_time_ms; }
-
- int UsagePercent() { return metrics_.encode_usage_percent; }
-
- CpuOveruseOptions options_;
- rtc::scoped_ptr<SimulatedClock> clock_;
- rtc::scoped_ptr<MockCpuOveruseObserver> observer_;
- rtc::scoped_ptr<OveruseFrameDetector> overuse_detector_;
- CpuOveruseMetrics metrics_;
-};
-
-
-// enable_encode_usage_method = true;
-// enable_extended_processing_usage = false;
-// UsagePercent() > high_encode_usage_threshold_percent => overuse.
-// UsagePercent() < low_encode_usage_threshold_percent => underuse.
-TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
- options_.enable_extended_processing_usage = false;
- ReinitializeOveruseDetector();
- // usage > high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- TriggerOveruse(options_.high_threshold_consecutive_count);
-}
-
-TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
- options_.enable_extended_processing_usage = false;
- ReinitializeOveruseDetector();
- // usage > high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- // usage < low => underuse
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
- options_.enable_extended_processing_usage = false;
- overuse_detector_.reset(
- new OveruseFrameDetector(clock_.get(), options_, nullptr, this));
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithMethodDisabled) {
- options_.enable_encode_usage_method = false;
- options_.enable_extended_processing_usage = false;
- ReinitializeOveruseDetector();
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
- options_.enable_extended_processing_usage = false;
- ReinitializeOveruseDetector();
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
- options_.enable_extended_processing_usage = false;
- options_.min_process_count = 1;
- CpuOveruseObserverImpl overuse_observer;
- overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_,
- &overuse_observer, this));
- InsertAndSendFramesWithInterval(
- 1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
- overuse_detector_->Process();
- EXPECT_EQ(0, overuse_observer.normaluse_);
- clock_->AdvanceTimeMilliseconds(kProcessIntervalMs);
- overuse_detector_->Process();
- EXPECT_EQ(1, overuse_observer.normaluse_);
-}
-
-TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
- options_.enable_extended_processing_usage = false;
- ReinitializeOveruseDetector();
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64);
- for(size_t i = 0; i < 64; ++i) {
- TriggerOveruse(options_.high_threshold_consecutive_count);
- }
-}
-
-TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- options_.enable_extended_processing_usage = false;
- options_.high_threshold_consecutive_count = 2;
- ReinitializeOveruseDetector();
- TriggerOveruse(2);
-}
-
-TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
- options_.enable_extended_processing_usage = false;
- options_.high_threshold_consecutive_count = 2;
- ReinitializeOveruseDetector();
- TriggerOveruse(1);
-}
-
-TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
- InsertAndSendFramesWithInterval(
- 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
- EXPECT_EQ(kProcessTime5ms * 100 / kFrameInterval33ms, UsagePercent());
-}
-
-TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
- EXPECT_EQ(InitialUsage(), UsagePercent());
- InsertAndSendFramesWithInterval(
- 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
- EXPECT_NE(InitialUsage(), UsagePercent());
- // Verify reset.
- InsertAndSendFramesWithInterval(
- 1, kFrameInterval33ms, kWidth, kHeight + 1, kProcessTime5ms);
- EXPECT_EQ(InitialUsage(), UsagePercent());
-}
-
-TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
- EXPECT_EQ(InitialUsage(), UsagePercent());
- InsertAndSendFramesWithInterval(
- 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
- EXPECT_NE(InitialUsage(), UsagePercent());
- InsertAndSendFramesWithInterval(
- 2, options_.frame_timeout_interval_ms, kWidth, kHeight, kProcessTime5ms);
- EXPECT_NE(InitialUsage(), UsagePercent());
- // Verify reset.
- InsertAndSendFramesWithInterval(
- 2, options_.frame_timeout_interval_ms + 1, kWidth, kHeight,
- kProcessTime5ms);
- EXPECT_EQ(InitialUsage(), UsagePercent());
-}
-
-TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
- options_.min_frame_samples = 40;
- ReinitializeOveruseDetector();
- InsertAndSendFramesWithInterval(
- 40, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
- EXPECT_EQ(InitialUsage(), UsagePercent());
- InsertAndSendFramesWithInterval(
- 1, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
- EXPECT_NE(InitialUsage(), UsagePercent());
-}
-
-TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
- EXPECT_EQ(InitialUsage(), UsagePercent());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrameDisabled) {
- options_.enable_extended_processing_usage = false;
- ReinitializeOveruseDetector();
- const int kProcessingTimeMs = 100;
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- overuse_detector_->FrameSent(33);
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrame) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- const int kProcessingTimeMs = 100;
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
- overuse_detector_->FrameSent(33);
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
- EXPECT_EQ(0, overuse_detector_->FramesInQueue());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_TwoFrames) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- const int kProcessingTimeMs1 = 100;
- const int kProcessingTimeMs2 = 50;
- const int kTimeBetweenFramesMs = 200;
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs1);
- overuse_detector_->FrameSent(33);
- EXPECT_EQ(kProcessingTimeMs1, overuse_detector_->LastProcessingTimeMs());
- clock_->AdvanceTimeMilliseconds(kTimeBetweenFramesMs);
- overuse_detector_->FrameCaptured(kWidth, kHeight, 66);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs2);
- overuse_detector_->FrameSent(66);
- EXPECT_EQ(kProcessingTimeMs2, overuse_detector_->LastProcessingTimeMs());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_MaxQueueSize) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- const int kMaxQueueSize = 91;
- for (int i = 0; i < kMaxQueueSize * 2; ++i) {
- overuse_detector_->FrameCaptured(kWidth, kHeight, i);
- }
- EXPECT_EQ(kMaxQueueSize, overuse_detector_->FramesInQueue());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_NonProcessedFramesRemoved) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- const int kProcessingTimeMs = 100;
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- overuse_detector_->FrameCaptured(kWidth, kHeight, 35);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- overuse_detector_->FrameCaptured(kWidth, kHeight, 66);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- overuse_detector_->FrameCaptured(kWidth, kHeight, 99);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
- EXPECT_EQ(4, overuse_detector_->FramesInQueue());
- overuse_detector_->FrameSent(66);
- // Frame 33, 35 removed, 66 processed, 99 not processed.
- EXPECT_EQ(2 * kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
- EXPECT_EQ(1, overuse_detector_->FramesInQueue());
- overuse_detector_->FrameSent(99);
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
- EXPECT_EQ(0, overuse_detector_->FramesInQueue());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_ResetClearsFrames) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- const int kProcessingTimeMs = 100;
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
- EXPECT_EQ(1, overuse_detector_->FramesInQueue());
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- // Verify reset (resolution changed).
- overuse_detector_->FrameCaptured(kWidth, kHeight + 1, 66);
- EXPECT_EQ(1, overuse_detector_->FramesInQueue());
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- overuse_detector_->FrameSent(66);
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
- EXPECT_EQ(0, overuse_detector_->FramesInQueue());
-}
-
-TEST_F(OveruseFrameDetectorTest, FrameDelay_NonMatchingSendFrameIgnored) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- const int kProcessingTimeMs = 100;
- overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
- clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
- overuse_detector_->FrameSent(34);
- EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
- overuse_detector_->FrameSent(33);
- EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
-}
-
-TEST_F(OveruseFrameDetectorTest, EncodedFrame) {
- const int kInitialAvgEncodeTimeInMs = 5;
- EXPECT_EQ(kInitialAvgEncodeTimeInMs, AvgEncodeTimeMs());
- for (int i = 0; i < 30; i++) {
- clock_->AdvanceTimeMilliseconds(33);
- overuse_detector_->FrameEncoded(2);
- }
- EXPECT_EQ(2, AvgEncodeTimeMs());
-}
-
-// enable_encode_usage_method = true;
-// enable_extended_processing_usage = true;
-// UsagePercent() > high_encode_usage_threshold_percent => overuse.
-// UsagePercent() < low_encode_usage_threshold_percent => underuse.
-TEST_F(OveruseFrameDetectorTest, TriggerOveruseWithExtendedProcessingUsage) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- // usage > high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- TriggerOveruse(options_.high_threshold_consecutive_count);
-}
-
-TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithExtendedProcessingUsage) {
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- // usage > high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- // usage < low => underuse
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
- TriggerUnderuse();
-}
-
-TEST_F(OveruseFrameDetectorTest,
- OveruseAndRecoverWithExtendedProcessingUsageMethodDisabled) {
- options_.enable_encode_usage_method = false;
- options_.enable_extended_processing_usage = true;
- ReinitializeOveruseDetector();
- // usage > high => overuse
- EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
- TriggerOveruse(options_.high_threshold_consecutive_count);
- // usage < low => underuse
- EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
- TriggerUnderuse();
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/payload_router.cc b/webrtc/video_engine/payload_router.cc
deleted file mode 100644
index 3af3d4829e..0000000000
--- a/webrtc/video_engine/payload_router.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2015 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/payload_router.h"
-
-#include "webrtc/base/checks.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-
-namespace webrtc {
-
-PayloadRouter::PayloadRouter()
- : crit_(CriticalSectionWrapper::CreateCriticalSection()),
- active_(false) {}
-
-PayloadRouter::~PayloadRouter() {}
-
-size_t PayloadRouter::DefaultMaxPayloadLength() {
- const size_t kIpUdpSrtpLength = 44;
- return IP_PACKET_SIZE - kIpUdpSrtpLength;
-}
-
-void PayloadRouter::SetSendingRtpModules(
- const std::list<RtpRtcp*>& rtp_modules) {
- CriticalSectionScoped cs(crit_.get());
- rtp_modules_.clear();
- rtp_modules_.reserve(rtp_modules.size());
- for (auto* rtp_module : rtp_modules) {
- rtp_modules_.push_back(rtp_module);
- }
-}
-
-void PayloadRouter::set_active(bool active) {
- CriticalSectionScoped cs(crit_.get());
- active_ = active;
-}
-
-bool PayloadRouter::active() {
- CriticalSectionScoped cs(crit_.get());
- return active_ && !rtp_modules_.empty();
-}
-
-bool PayloadRouter::RoutePayload(FrameType frame_type,
- int8_t payload_type,
- uint32_t time_stamp,
- int64_t capture_time_ms,
- const uint8_t* payload_data,
- size_t payload_length,
- const RTPFragmentationHeader* fragmentation,
- const RTPVideoHeader* rtp_video_hdr) {
- CriticalSectionScoped cs(crit_.get());
- if (!active_ || rtp_modules_.empty())
- return false;
-
- // The simulcast index might actually be larger than the number of modules in
- // case the encoder was processing a frame during a codec reconfig.
- if (rtp_video_hdr != NULL &&
- rtp_video_hdr->simulcastIdx >= rtp_modules_.size())
- return false;
-
- int stream_idx = 0;
- if (rtp_video_hdr != NULL)
- stream_idx = rtp_video_hdr->simulcastIdx;
- return rtp_modules_[stream_idx]->SendOutgoingData(
- frame_type, payload_type, time_stamp, capture_time_ms, payload_data,
- payload_length, fragmentation, rtp_video_hdr) == 0 ? true : false;
-}
-
-void PayloadRouter::SetTargetSendBitrates(
- const std::vector<uint32_t>& stream_bitrates) {
- CriticalSectionScoped cs(crit_.get());
- if (stream_bitrates.size() < rtp_modules_.size()) {
- // There can be a size mis-match during codec reconfiguration.
- return;
- }
- int idx = 0;
- for (auto* rtp_module : rtp_modules_) {
- rtp_module->SetTargetSendBitrate(stream_bitrates[idx++]);
- }
-}
-
-size_t PayloadRouter::MaxPayloadLength() const {
- size_t min_payload_length = DefaultMaxPayloadLength();
- CriticalSectionScoped cs(crit_.get());
- for (auto* rtp_module : rtp_modules_) {
- size_t module_payload_length = rtp_module->MaxDataPayloadLength();
- if (module_payload_length < min_payload_length)
- min_payload_length = module_payload_length;
- }
- return min_payload_length;
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/payload_router.h b/webrtc/video_engine/payload_router.h
deleted file mode 100644
index 17bc279290..0000000000
--- a/webrtc/video_engine/payload_router.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2015 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_PAYLOAD_ROUTER_H_
-#define WEBRTC_VIDEO_ENGINE_PAYLOAD_ROUTER_H_
-
-#include <list>
-#include <vector>
-
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/thread_annotations.h"
-#include "webrtc/common_types.h"
-#include "webrtc/system_wrappers/include/atomic32.h"
-
-namespace webrtc {
-
-class CriticalSectionWrapper;
-class RTPFragmentationHeader;
-class RtpRtcp;
-struct RTPVideoHeader;
-
-// PayloadRouter routes outgoing data to the correct sending RTP module, based
-// on the simulcast layer in RTPVideoHeader.
-class PayloadRouter {
- public:
- PayloadRouter();
- ~PayloadRouter();
-
- static size_t DefaultMaxPayloadLength();
-
- // Rtp modules are assumed to be sorted in simulcast index order.
- void SetSendingRtpModules(const std::list<RtpRtcp*>& rtp_modules);
-
- // PayloadRouter will only route packets if being active, all packets will be
- // dropped otherwise.
- void set_active(bool active);
- bool active();
-
- // Input parameters according to the signature of RtpRtcp::SendOutgoingData.
- // Returns true if the packet was routed / sent, false otherwise.
- bool RoutePayload(FrameType frame_type,
- int8_t payload_type,
- uint32_t time_stamp,
- int64_t capture_time_ms,
- const uint8_t* payload_data,
- size_t payload_size,
- const RTPFragmentationHeader* fragmentation,
- const RTPVideoHeader* rtp_video_hdr);
-
- // Configures current target bitrate per module. 'stream_bitrates' is assumed
- // to be in the same order as 'SetSendingRtpModules'.
- void SetTargetSendBitrates(const std::vector<uint32_t>& stream_bitrates);
-
- // Returns the maximum allowed data payload length, given the configured MTU
- // and RTP headers.
- size_t MaxPayloadLength() const;
-
- void AddRef() { ++ref_count_; }
- void Release() { if (--ref_count_ == 0) { delete this; } }
-
- private:
- // TODO(mflodman): When the new video API has launched, remove crit_ and
- // assume rtp_modules_ will never change during a call.
- rtc::scoped_ptr<CriticalSectionWrapper> crit_;
-
- // Active sending RTP modules, in layer order.
- std::vector<RtpRtcp*> rtp_modules_ GUARDED_BY(crit_.get());
- bool active_ GUARDED_BY(crit_.get());
-
- Atomic32 ref_count_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(PayloadRouter);
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_PAYLOAD_ROUTER_H_
diff --git a/webrtc/video_engine/payload_router_unittest.cc b/webrtc/video_engine/payload_router_unittest.cc
deleted file mode 100644
index de391576d8..0000000000
--- a/webrtc/video_engine/payload_router_unittest.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2015 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 <list>
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
-#include "webrtc/video_engine/payload_router.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::NiceMock;
-using ::testing::Return;
-
-namespace webrtc {
-
-class PayloadRouterTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- payload_router_.reset(new PayloadRouter());
- }
- rtc::scoped_ptr<PayloadRouter> payload_router_;
-};
-
-TEST_F(PayloadRouterTest, SendOnOneModule) {
- MockRtpRtcp rtp;
- std::list<RtpRtcp*> modules(1, &rtp);
-
- payload_router_->SetSendingRtpModules(modules);
-
- uint8_t payload = 'a';
- FrameType frame_type = kVideoFrameKey;
- int8_t payload_type = 96;
-
- EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
- NULL))
- .Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, NULL, NULL));
-
- payload_router_->set_active(true);
- EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
- NULL))
- .Times(1);
- EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, NULL, NULL));
-
- payload_router_->set_active(false);
- EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
- NULL))
- .Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, NULL, NULL));
-
- payload_router_->set_active(true);
- EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
- NULL))
- .Times(1);
- EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, NULL, NULL));
-
- modules.clear();
- payload_router_->SetSendingRtpModules(modules);
- EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
- NULL))
- .Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
- &payload, 1, NULL, NULL));
-}
-
-TEST_F(PayloadRouterTest, SendSimulcast) {
- MockRtpRtcp rtp_1;
- MockRtpRtcp rtp_2;
- std::list<RtpRtcp*> modules;
- modules.push_back(&rtp_1);
- modules.push_back(&rtp_2);
-
- payload_router_->SetSendingRtpModules(modules);
-
- uint8_t payload_1 = 'a';
- FrameType frame_type_1 = kVideoFrameKey;
- int8_t payload_type_1 = 96;
- RTPVideoHeader rtp_hdr_1;
- rtp_hdr_1.simulcastIdx = 0;
-
- payload_router_->set_active(true);
- EXPECT_CALL(rtp_1, SendOutgoingData(frame_type_1, payload_type_1, 0, 0, _, 1,
- NULL, &rtp_hdr_1))
- .Times(1);
- EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
- .Times(0);
- EXPECT_TRUE(payload_router_->RoutePayload(frame_type_1, payload_type_1, 0, 0,
- &payload_1, 1, NULL, &rtp_hdr_1));
-
- uint8_t payload_2 = 'b';
- FrameType frame_type_2 = kVideoFrameDelta;
- int8_t payload_type_2 = 97;
- RTPVideoHeader rtp_hdr_2;
- rtp_hdr_2.simulcastIdx = 1;
- EXPECT_CALL(rtp_2, SendOutgoingData(frame_type_2, payload_type_2, 0, 0, _, 1,
- NULL, &rtp_hdr_2))
- .Times(1);
- EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
- .Times(0);
- EXPECT_TRUE(payload_router_->RoutePayload(frame_type_2, payload_type_2, 0, 0,
- &payload_2, 1, NULL, &rtp_hdr_2));
-
- // Inactive.
- payload_router_->set_active(false);
- EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
- .Times(0);
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type_1, payload_type_1, 0, 0,
- &payload_1, 1, NULL, &rtp_hdr_1));
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type_2, payload_type_2, 0, 0,
- &payload_2, 1, NULL, &rtp_hdr_2));
-
- // Invalid simulcast index.
- payload_router_->set_active(true);
- EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
- .Times(0);
- EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
- .Times(0);
- rtp_hdr_1.simulcastIdx = 2;
- EXPECT_FALSE(payload_router_->RoutePayload(frame_type_1, payload_type_1, 0, 0,
- &payload_1, 1, NULL, &rtp_hdr_1));
-}
-
-TEST_F(PayloadRouterTest, MaxPayloadLength) {
- // Without any limitations from the modules, verify we get the max payload
- // length for IP/UDP/SRTP with a MTU of 150 bytes.
- const size_t kDefaultMaxLength = 1500 - 20 - 8 - 12 - 4;
- EXPECT_EQ(kDefaultMaxLength, payload_router_->DefaultMaxPayloadLength());
- EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());
-
- MockRtpRtcp rtp_1;
- MockRtpRtcp rtp_2;
- std::list<RtpRtcp*> modules;
- modules.push_back(&rtp_1);
- modules.push_back(&rtp_2);
- payload_router_->SetSendingRtpModules(modules);
-
- // Modules return a higher length than the default value.
- EXPECT_CALL(rtp_1, MaxDataPayloadLength())
- .Times(1)
- .WillOnce(Return(kDefaultMaxLength + 10));
- EXPECT_CALL(rtp_2, MaxDataPayloadLength())
- .Times(1)
- .WillOnce(Return(kDefaultMaxLength + 10));
- EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());
-
- // The modules return a value lower than default.
- const size_t kTestMinPayloadLength = 1001;
- EXPECT_CALL(rtp_1, MaxDataPayloadLength())
- .Times(1)
- .WillOnce(Return(kTestMinPayloadLength + 10));
- EXPECT_CALL(rtp_2, MaxDataPayloadLength())
- .Times(1)
- .WillOnce(Return(kTestMinPayloadLength));
- EXPECT_EQ(kTestMinPayloadLength, payload_router_->MaxPayloadLength());
-}
-
-TEST_F(PayloadRouterTest, SetTargetSendBitrates) {
- MockRtpRtcp rtp_1;
- MockRtpRtcp rtp_2;
- std::list<RtpRtcp*> modules;
- modules.push_back(&rtp_1);
- modules.push_back(&rtp_2);
- payload_router_->SetSendingRtpModules(modules);
-
- const uint32_t bitrate_1 = 10000;
- const uint32_t bitrate_2 = 76543;
- std::vector<uint32_t> bitrates (2, bitrate_1);
- bitrates[1] = bitrate_2;
- EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
- .Times(1);
- EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
- .Times(1);
- payload_router_->SetTargetSendBitrates(bitrates);
-
- bitrates.resize(1);
- EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
- .Times(0);
- EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
- .Times(0);
- payload_router_->SetTargetSendBitrates(bitrates);
-
- bitrates.resize(3);
- bitrates[1] = bitrate_2;
- bitrates[2] = bitrate_1 + bitrate_2;
- EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
- .Times(1);
- EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
- .Times(1);
- payload_router_->SetTargetSendBitrates(bitrates);
-}
-} // namespace webrtc
diff --git a/webrtc/video_engine/report_block_stats.cc b/webrtc/video_engine/report_block_stats.cc
deleted file mode 100644
index 6df62882d8..0000000000
--- a/webrtc/video_engine/report_block_stats.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2014 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/report_block_stats.h"
-
-namespace webrtc {
-
-namespace {
-int FractionLost(uint32_t num_lost_sequence_numbers,
- uint32_t num_sequence_numbers) {
- if (num_sequence_numbers == 0) {
- return 0;
- }
- return ((num_lost_sequence_numbers * 255) + (num_sequence_numbers / 2)) /
- num_sequence_numbers;
-}
-} // namespace
-
-
-// Helper class for rtcp statistics.
-ReportBlockStats::ReportBlockStats()
- : num_sequence_numbers_(0),
- num_lost_sequence_numbers_(0) {
-}
-
-void ReportBlockStats::Store(const RtcpStatistics& rtcp_stats,
- uint32_t remote_ssrc,
- uint32_t source_ssrc) {
- RTCPReportBlock block;
- block.cumulativeLost = rtcp_stats.cumulative_lost;
- block.fractionLost = rtcp_stats.fraction_lost;
- block.extendedHighSeqNum = rtcp_stats.extended_max_sequence_number;
- block.jitter = rtcp_stats.jitter;
- block.remoteSSRC = remote_ssrc;
- block.sourceSSRC = source_ssrc;
- uint32_t num_sequence_numbers = 0;
- uint32_t num_lost_sequence_numbers = 0;
- StoreAndAddPacketIncrement(
- block, &num_sequence_numbers, &num_lost_sequence_numbers);
-}
-
-RTCPReportBlock ReportBlockStats::AggregateAndStore(
- const ReportBlockVector& report_blocks) {
- RTCPReportBlock aggregate;
- if (report_blocks.empty()) {
- return aggregate;
- }
- uint32_t num_sequence_numbers = 0;
- uint32_t num_lost_sequence_numbers = 0;
- ReportBlockVector::const_iterator report_block = report_blocks.begin();
- for (; report_block != report_blocks.end(); ++report_block) {
- aggregate.cumulativeLost += report_block->cumulativeLost;
- aggregate.jitter += report_block->jitter;
- StoreAndAddPacketIncrement(*report_block,
- &num_sequence_numbers,
- &num_lost_sequence_numbers);
- }
-
- if (report_blocks.size() == 1) {
- // No aggregation needed.
- return report_blocks[0];
- }
- // Fraction lost since previous report block.
- aggregate.fractionLost =
- FractionLost(num_lost_sequence_numbers, num_sequence_numbers);
- aggregate.jitter = static_cast<uint32_t>(
- (aggregate.jitter + report_blocks.size() / 2) / report_blocks.size());
- return aggregate;
-}
-
-void ReportBlockStats::StoreAndAddPacketIncrement(
- const RTCPReportBlock& report_block,
- uint32_t* num_sequence_numbers,
- uint32_t* num_lost_sequence_numbers) {
- // Get diff with previous report block.
- ReportBlockMap::iterator prev_report_block = prev_report_blocks_.find(
- report_block.sourceSSRC);
- if (prev_report_block != prev_report_blocks_.end()) {
- int seq_num_diff = report_block.extendedHighSeqNum -
- prev_report_block->second.extendedHighSeqNum;
- int cum_loss_diff = report_block.cumulativeLost -
- prev_report_block->second.cumulativeLost;
- if (seq_num_diff >= 0 && cum_loss_diff >= 0) {
- *num_sequence_numbers += seq_num_diff;
- *num_lost_sequence_numbers += cum_loss_diff;
- // Update total number of packets/lost packets.
- num_sequence_numbers_ += seq_num_diff;
- num_lost_sequence_numbers_ += cum_loss_diff;
- }
- }
- // Store current report block.
- prev_report_blocks_[report_block.sourceSSRC] = report_block;
-}
-
-int ReportBlockStats::FractionLostInPercent() const {
- if (num_sequence_numbers_ == 0) {
- return -1;
- }
- return FractionLost(
- num_lost_sequence_numbers_, num_sequence_numbers_) * 100 / 255;
-}
-
-} // namespace webrtc
-
diff --git a/webrtc/video_engine/report_block_stats.h b/webrtc/video_engine/report_block_stats.h
deleted file mode 100644
index dadcc9d410..0000000000
--- a/webrtc/video_engine/report_block_stats.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_REPORT_BLOCK_STATS_H_
-#define WEBRTC_VIDEO_ENGINE_REPORT_BLOCK_STATS_H_
-
-#include <map>
-#include <vector>
-
-#include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-
-namespace webrtc {
-
-// Helper class for rtcp statistics.
-class ReportBlockStats {
- public:
- typedef std::map<uint32_t, RTCPReportBlock> ReportBlockMap;
- typedef std::vector<RTCPReportBlock> ReportBlockVector;
- ReportBlockStats();
- ~ReportBlockStats() {}
-
- // Updates stats and stores report blocks.
- // Returns an aggregate of the |report_blocks|.
- RTCPReportBlock AggregateAndStore(const ReportBlockVector& report_blocks);
-
- // Updates stats and stores report block.
- void Store(const RtcpStatistics& rtcp_stats,
- uint32_t remote_ssrc,
- uint32_t source_ssrc);
-
- // Returns the total fraction of lost packets (or -1 if less than two report
- // blocks have been stored).
- int FractionLostInPercent() const;
-
- private:
- // Updates the total number of packets/lost packets.
- // Stores the report block.
- // Returns the number of packets/lost packets since previous report block.
- void StoreAndAddPacketIncrement(const RTCPReportBlock& report_block,
- uint32_t* num_sequence_numbers,
- uint32_t* num_lost_sequence_numbers);
-
- // The total number of packets/lost packets.
- uint32_t num_sequence_numbers_;
- uint32_t num_lost_sequence_numbers_;
-
- // Map holding the last stored report block (mapped by the source SSRC).
- ReportBlockMap prev_report_blocks_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_REPORT_BLOCK_STATS_H_
-
diff --git a/webrtc/video_engine/report_block_stats_unittest.cc b/webrtc/video_engine/report_block_stats_unittest.cc
deleted file mode 100644
index 13b7af5ba2..0000000000
--- a/webrtc/video_engine/report_block_stats_unittest.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2014 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 "testing/gtest/include/gtest/gtest.h"
-
-#include "webrtc/video_engine/report_block_stats.h"
-
-namespace webrtc {
-
-class ReportBlockStatsTest : public ::testing::Test {
- protected:
- ReportBlockStatsTest() : kSsrc1(0x12345), kSsrc2(0x23456) {}
-
- void SetUp() override {
- // kSsrc1: block 1-3.
- block1_1_.cumulativeLost = 10;
- block1_1_.fractionLost = 123;
- block1_1_.extendedHighSeqNum = 24000;
- block1_1_.jitter = 777;
- block1_1_.sourceSSRC = kSsrc1;
- block1_2_.cumulativeLost = 15;
- block1_2_.fractionLost = 0;
- block1_2_.extendedHighSeqNum = 24100;
- block1_2_.jitter = 222;
- block1_2_.sourceSSRC = kSsrc1;
- block1_3_.cumulativeLost = 50;
- block1_3_.fractionLost = 0;
- block1_3_.extendedHighSeqNum = 24200;
- block1_3_.jitter = 333;
- block1_3_.sourceSSRC = kSsrc1;
- // kSsrc2: block 1,2.
- block2_1_.cumulativeLost = 111;
- block2_1_.fractionLost = 222;
- block2_1_.extendedHighSeqNum = 8500;
- block2_1_.jitter = 555;
- block2_1_.sourceSSRC = kSsrc2;
- block2_2_.cumulativeLost = 136;
- block2_2_.fractionLost = 0;
- block2_2_.extendedHighSeqNum = 8800;
- block2_2_.jitter = 888;
- block2_2_.sourceSSRC = kSsrc2;
-
- ssrc1block1_.push_back(block1_1_);
- ssrc1block2_.push_back(block1_2_);
- ssrc12block1_.push_back(block1_1_);
- ssrc12block1_.push_back(block2_1_);
- ssrc12block2_.push_back(block1_2_);
- ssrc12block2_.push_back(block2_2_);
- }
-
- RtcpStatistics RtcpReportBlockToRtcpStatistics(
- const RTCPReportBlock& stats) {
- RtcpStatistics block;
- block.cumulative_lost = stats.cumulativeLost;
- block.fraction_lost = stats.fractionLost;
- block.extended_max_sequence_number = stats.extendedHighSeqNum;
- block.jitter = stats.jitter;
- return block;
- }
-
- const uint32_t kSsrc1;
- const uint32_t kSsrc2;
- RTCPReportBlock block1_1_;
- RTCPReportBlock block1_2_;
- RTCPReportBlock block1_3_;
- RTCPReportBlock block2_1_;
- RTCPReportBlock block2_2_;
- std::vector<RTCPReportBlock> ssrc1block1_;
- std::vector<RTCPReportBlock> ssrc1block2_;
- std::vector<RTCPReportBlock> ssrc12block1_;
- std::vector<RTCPReportBlock> ssrc12block2_;
-};
-
-TEST_F(ReportBlockStatsTest, AggregateAndStore_NoSsrc) {
- ReportBlockStats stats;
- std::vector<RTCPReportBlock> empty;
- RTCPReportBlock aggregated = stats.AggregateAndStore(empty);
- EXPECT_EQ(0U, aggregated.fractionLost);
- EXPECT_EQ(0U, aggregated.cumulativeLost);
- EXPECT_EQ(0U, aggregated.jitter);
- EXPECT_EQ(0U, aggregated.extendedHighSeqNum);
-}
-
-TEST_F(ReportBlockStatsTest, AggregateAndStore_OneSsrc) {
- ReportBlockStats stats;
- RTCPReportBlock aggregated = stats.AggregateAndStore(ssrc1block1_);
- // One ssrc, no aggregation done.
- EXPECT_EQ(123U, aggregated.fractionLost);
- EXPECT_EQ(10U, aggregated.cumulativeLost);
- EXPECT_EQ(777U, aggregated.jitter);
- EXPECT_EQ(24000U, aggregated.extendedHighSeqNum);
-
- aggregated = stats.AggregateAndStore(ssrc1block2_);
- EXPECT_EQ(0U, aggregated.fractionLost);
- EXPECT_EQ(15U, aggregated.cumulativeLost);
- EXPECT_EQ(222U, aggregated.jitter);
- EXPECT_EQ(24100U, aggregated.extendedHighSeqNum);
-
- // fl: 100 * (15-10) / (24100-24000) = 5%
- EXPECT_EQ(5, stats.FractionLostInPercent());
-}
-
-TEST_F(ReportBlockStatsTest, AggregateAndStore_TwoSsrcs) {
- ReportBlockStats stats;
- RTCPReportBlock aggregated = stats.AggregateAndStore(ssrc12block1_);
- EXPECT_EQ(0U, aggregated.fractionLost);
- EXPECT_EQ(10U + 111U, aggregated.cumulativeLost);
- EXPECT_EQ((777U + 555U) / 2, aggregated.jitter);
- EXPECT_EQ(0U, aggregated.extendedHighSeqNum);
-
- aggregated = stats.AggregateAndStore(ssrc12block2_);
- // fl: 255 * ((15-10) + (136-111)) / ((24100-24000) + (8800-8500)) = 19
- EXPECT_EQ(19U, aggregated.fractionLost);
- EXPECT_EQ(15U + 136U, aggregated.cumulativeLost);
- EXPECT_EQ((222U + 888U) / 2, aggregated.jitter);
- EXPECT_EQ(0U, aggregated.extendedHighSeqNum);
-
- // fl: 100 * ((15-10) + (136-111)) / ((24100-24000) + (8800-8500)) = 7%
- EXPECT_EQ(7, stats.FractionLostInPercent());
-}
-
-TEST_F(ReportBlockStatsTest, StoreAndGetFractionLost) {
- const uint32_t kRemoteSsrc = 1;
- ReportBlockStats stats;
- EXPECT_EQ(-1, stats.FractionLostInPercent());
-
- // First block.
- stats.Store(RtcpReportBlockToRtcpStatistics(block1_1_), kRemoteSsrc, kSsrc1);
- EXPECT_EQ(-1, stats.FractionLostInPercent());
- // fl: 100 * (15-10) / (24100-24000) = 5%
- stats.Store(RtcpReportBlockToRtcpStatistics(block1_2_), kRemoteSsrc, kSsrc1);
- EXPECT_EQ(5, stats.FractionLostInPercent());
- // fl: 100 * (50-10) / (24200-24000) = 20%
- stats.Store(RtcpReportBlockToRtcpStatistics(block1_3_), kRemoteSsrc, kSsrc1);
- EXPECT_EQ(20, stats.FractionLostInPercent());
-}
-
-} // namespace webrtc
-
diff --git a/webrtc/video_engine/stream_synchronization.cc b/webrtc/video_engine/stream_synchronization.cc
deleted file mode 100644
index b78cfe8874..0000000000
--- a/webrtc/video_engine/stream_synchronization.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * 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/stream_synchronization.h"
-
-#include <assert.h>
-#include <math.h>
-#include <stdlib.h>
-
-#include <algorithm>
-
-#include "webrtc/base/logging.h"
-
-namespace webrtc {
-
-static const int kMaxChangeMs = 80;
-static const int kMaxDeltaDelayMs = 10000;
-static const int kFilterLength = 4;
-// Minimum difference between audio and video to warrant a change.
-static const int kMinDeltaMs = 30;
-
-struct ViESyncDelay {
- ViESyncDelay() {
- extra_video_delay_ms = 0;
- last_video_delay_ms = 0;
- extra_audio_delay_ms = 0;
- last_audio_delay_ms = 0;
- network_delay = 120;
- }
-
- int extra_video_delay_ms;
- int last_video_delay_ms;
- int extra_audio_delay_ms;
- int last_audio_delay_ms;
- int network_delay;
-};
-
-StreamSynchronization::StreamSynchronization(uint32_t video_primary_ssrc,
- int audio_channel_id)
- : channel_delay_(new ViESyncDelay),
- video_primary_ssrc_(video_primary_ssrc),
- audio_channel_id_(audio_channel_id),
- base_target_delay_ms_(0),
- avg_diff_ms_(0) {
-}
-
-StreamSynchronization::~StreamSynchronization() {
- delete channel_delay_;
-}
-
-bool StreamSynchronization::ComputeRelativeDelay(
- const Measurements& audio_measurement,
- const Measurements& video_measurement,
- int* relative_delay_ms) {
- assert(relative_delay_ms);
- if (audio_measurement.rtcp.size() < 2 || video_measurement.rtcp.size() < 2) {
- // We need two RTCP SR reports per stream to do synchronization.
- return false;
- }
- int64_t audio_last_capture_time_ms;
- if (!RtpToNtpMs(audio_measurement.latest_timestamp,
- audio_measurement.rtcp,
- &audio_last_capture_time_ms)) {
- return false;
- }
- int64_t video_last_capture_time_ms;
- if (!RtpToNtpMs(video_measurement.latest_timestamp,
- video_measurement.rtcp,
- &video_last_capture_time_ms)) {
- return false;
- }
- if (video_last_capture_time_ms < 0) {
- return false;
- }
- // Positive diff means that video_measurement is behind audio_measurement.
- *relative_delay_ms = video_measurement.latest_receive_time_ms -
- audio_measurement.latest_receive_time_ms -
- (video_last_capture_time_ms - audio_last_capture_time_ms);
- if (*relative_delay_ms > kMaxDeltaDelayMs ||
- *relative_delay_ms < -kMaxDeltaDelayMs) {
- return false;
- }
- return true;
-}
-
-bool StreamSynchronization::ComputeDelays(int relative_delay_ms,
- int current_audio_delay_ms,
- int* total_audio_delay_target_ms,
- int* total_video_delay_target_ms) {
- assert(total_audio_delay_target_ms && total_video_delay_target_ms);
-
- int current_video_delay_ms = *total_video_delay_target_ms;
- LOG(LS_VERBOSE) << "Audio delay: " << current_audio_delay_ms
- << ", network delay diff: " << channel_delay_->network_delay
- << " current diff: " << relative_delay_ms
- << " for channel " << audio_channel_id_;
- // Calculate the difference between the lowest possible video delay and
- // the current audio delay.
- int current_diff_ms = current_video_delay_ms - current_audio_delay_ms +
- relative_delay_ms;
-
- avg_diff_ms_ = ((kFilterLength - 1) * avg_diff_ms_ +
- current_diff_ms) / kFilterLength;
- if (abs(avg_diff_ms_) < kMinDeltaMs) {
- // Don't adjust if the diff is within our margin.
- return false;
- }
-
- // Make sure we don't move too fast.
- int diff_ms = avg_diff_ms_ / 2;
- diff_ms = std::min(diff_ms, kMaxChangeMs);
- diff_ms = std::max(diff_ms, -kMaxChangeMs);
-
- // Reset the average after a move to prevent overshooting reaction.
- avg_diff_ms_ = 0;
-
- if (diff_ms > 0) {
- // The minimum video delay is longer than the current audio delay.
- // We need to decrease extra video delay, or add extra audio delay.
- if (channel_delay_->extra_video_delay_ms > base_target_delay_ms_) {
- // We have extra delay added to ViE. Reduce this delay before adding
- // extra delay to VoE.
- channel_delay_->extra_video_delay_ms -= diff_ms;
- channel_delay_->extra_audio_delay_ms = base_target_delay_ms_;
- } else { // channel_delay_->extra_video_delay_ms > 0
- // We have no extra video delay to remove, increase the audio delay.
- channel_delay_->extra_audio_delay_ms += diff_ms;
- channel_delay_->extra_video_delay_ms = base_target_delay_ms_;
- }
- } else { // if (diff_ms > 0)
- // The video delay is lower than the current audio delay.
- // We need to decrease extra audio delay, or add extra video delay.
- if (channel_delay_->extra_audio_delay_ms > base_target_delay_ms_) {
- // We have extra delay in VoiceEngine.
- // Start with decreasing the voice delay.
- // Note: diff_ms is negative; add the negative difference.
- channel_delay_->extra_audio_delay_ms += diff_ms;
- channel_delay_->extra_video_delay_ms = base_target_delay_ms_;
- } else { // channel_delay_->extra_audio_delay_ms > base_target_delay_ms_
- // We have no extra delay in VoiceEngine, increase the video delay.
- // Note: diff_ms is negative; subtract the negative difference.
- channel_delay_->extra_video_delay_ms -= diff_ms; // X - (-Y) = X + Y.
- channel_delay_->extra_audio_delay_ms = base_target_delay_ms_;
- }
- }
-
- // Make sure that video is never below our target.
- channel_delay_->extra_video_delay_ms = std::max(
- channel_delay_->extra_video_delay_ms, base_target_delay_ms_);
-
- int new_video_delay_ms;
- if (channel_delay_->extra_video_delay_ms > base_target_delay_ms_) {
- new_video_delay_ms = channel_delay_->extra_video_delay_ms;
- } else {
- // No change to the extra video delay. We are changing audio and we only
- // allow to change one at the time.
- new_video_delay_ms = channel_delay_->last_video_delay_ms;
- }
-
- // Make sure that we don't go below the extra video delay.
- new_video_delay_ms = std::max(
- new_video_delay_ms, channel_delay_->extra_video_delay_ms);
-
- // Verify we don't go above the maximum allowed video delay.
- new_video_delay_ms =
- std::min(new_video_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
-
- int new_audio_delay_ms;
- if (channel_delay_->extra_audio_delay_ms > base_target_delay_ms_) {
- new_audio_delay_ms = channel_delay_->extra_audio_delay_ms;
- } else {
- // No change to the audio delay. We are changing video and we only
- // allow to change one at the time.
- new_audio_delay_ms = channel_delay_->last_audio_delay_ms;
- }
-
- // Make sure that we don't go below the extra audio delay.
- new_audio_delay_ms = std::max(
- new_audio_delay_ms, channel_delay_->extra_audio_delay_ms);
-
- // Verify we don't go above the maximum allowed audio delay.
- new_audio_delay_ms =
- std::min(new_audio_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
-
- // Remember our last audio and video delays.
- channel_delay_->last_video_delay_ms = new_video_delay_ms;
- channel_delay_->last_audio_delay_ms = new_audio_delay_ms;
-
- LOG(LS_VERBOSE) << "Sync video delay " << new_video_delay_ms
- << " for video primary SSRC " << video_primary_ssrc_
- << " and audio delay " << channel_delay_->extra_audio_delay_ms
- << " for audio channel " << audio_channel_id_;
-
- // Return values.
- *total_video_delay_target_ms = new_video_delay_ms;
- *total_audio_delay_target_ms = new_audio_delay_ms;
- return true;
-}
-
-void StreamSynchronization::SetTargetBufferingDelay(int target_delay_ms) {
- // Initial extra delay for audio (accounting for existing extra delay).
- channel_delay_->extra_audio_delay_ms +=
- target_delay_ms - base_target_delay_ms_;
- channel_delay_->last_audio_delay_ms +=
- target_delay_ms - base_target_delay_ms_;
-
- // The video delay is compared to the last value (and how much we can update
- // is limited by that as well).
- channel_delay_->last_video_delay_ms +=
- target_delay_ms - base_target_delay_ms_;
-
- channel_delay_->extra_video_delay_ms +=
- target_delay_ms - base_target_delay_ms_;
-
- // Video is already delayed by the desired amount.
- base_target_delay_ms_ = target_delay_ms;
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/stream_synchronization.h b/webrtc/video_engine/stream_synchronization.h
deleted file mode 100644
index 1209062f9b..0000000000
--- a/webrtc/video_engine/stream_synchronization.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_STREAM_SYNCHRONIZATION_H_
-#define WEBRTC_VIDEO_ENGINE_STREAM_SYNCHRONIZATION_H_
-
-#include <list>
-
-#include "webrtc/system_wrappers/include/rtp_to_ntp.h"
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-
-struct ViESyncDelay;
-
-class StreamSynchronization {
- public:
- struct Measurements {
- Measurements() : rtcp(), latest_receive_time_ms(0), latest_timestamp(0) {}
- RtcpList rtcp;
- int64_t latest_receive_time_ms;
- uint32_t latest_timestamp;
- };
-
- StreamSynchronization(uint32_t video_primary_ssrc, int audio_channel_id);
- ~StreamSynchronization();
-
- bool ComputeDelays(int relative_delay_ms,
- int current_audio_delay_ms,
- int* extra_audio_delay_ms,
- int* total_video_delay_target_ms);
-
- // On success |relative_delay| contains the number of milliseconds later video
- // is rendered relative audio. If audio is played back later than video a
- // |relative_delay| will be negative.
- static bool ComputeRelativeDelay(const Measurements& audio_measurement,
- const Measurements& video_measurement,
- int* relative_delay_ms);
- // Set target buffering delay - All audio and video will be delayed by at
- // least target_delay_ms.
- void SetTargetBufferingDelay(int target_delay_ms);
-
- private:
- ViESyncDelay* channel_delay_;
- const uint32_t video_primary_ssrc_;
- const int audio_channel_id_;
- int base_target_delay_ms_;
- int avg_diff_ms_;
-};
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_STREAM_SYNCHRONIZATION_H_
diff --git a/webrtc/video_engine/stream_synchronization_unittest.cc b/webrtc/video_engine/stream_synchronization_unittest.cc
deleted file mode 100644
index 7136f1e1c7..0000000000
--- a/webrtc/video_engine/stream_synchronization_unittest.cc
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * 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 <algorithm>
-#include <math.h>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/video_engine/stream_synchronization.h"
-
-namespace webrtc {
-
-// These correspond to the same constants defined in vie_sync_module.cc.
-enum { kMaxVideoDiffMs = 80 };
-enum { kMaxAudioDiffMs = 80 };
-enum { kMaxDelay = 1500 };
-
-// Test constants.
-enum { kDefaultAudioFrequency = 8000 };
-enum { kDefaultVideoFrequency = 90000 };
-const double kNtpFracPerMs = 4.294967296E6;
-static const int kSmoothingFilter = 4 * 2;
-
-class Time {
- public:
- explicit Time(int64_t offset)
- : kNtpJan1970(2208988800UL),
- time_now_ms_(offset) {}
-
- RtcpMeasurement GenerateRtcp(int frequency, uint32_t offset) const {
- RtcpMeasurement rtcp;
- NowNtp(&rtcp.ntp_secs, &rtcp.ntp_frac);
- rtcp.rtp_timestamp = NowRtp(frequency, offset);
- return rtcp;
- }
-
- void NowNtp(uint32_t* ntp_secs, uint32_t* ntp_frac) const {
- *ntp_secs = time_now_ms_ / 1000 + kNtpJan1970;
- int64_t remainder_ms = time_now_ms_ % 1000;
- *ntp_frac = static_cast<uint32_t>(
- static_cast<double>(remainder_ms) * kNtpFracPerMs + 0.5);
- }
-
- uint32_t NowRtp(int frequency, uint32_t offset) const {
- return frequency * time_now_ms_ / 1000 + offset;
- }
-
- void IncreaseTimeMs(int64_t inc) {
- time_now_ms_ += inc;
- }
-
- int64_t time_now_ms() const {
- return time_now_ms_;
- }
-
- private:
- // January 1970, in NTP seconds.
- const uint32_t kNtpJan1970;
- int64_t time_now_ms_;
-};
-
-class StreamSynchronizationTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- sync_ = new StreamSynchronization(0, 0);
- send_time_ = new Time(kSendTimeOffsetMs);
- receive_time_ = new Time(kReceiveTimeOffsetMs);
- audio_clock_drift_ = 1.0;
- video_clock_drift_ = 1.0;
- }
-
- virtual void TearDown() {
- delete sync_;
- delete send_time_;
- delete receive_time_;
- }
-
- // Generates the necessary RTCP measurements and RTP timestamps and computes
- // the audio and video delays needed to get the two streams in sync.
- // |audio_delay_ms| and |video_delay_ms| are the number of milliseconds after
- // capture which the frames are rendered.
- // |current_audio_delay_ms| is the number of milliseconds which audio is
- // currently being delayed by the receiver.
- bool DelayedStreams(int audio_delay_ms,
- int video_delay_ms,
- int current_audio_delay_ms,
- int* extra_audio_delay_ms,
- int* total_video_delay_ms) {
- int audio_frequency = static_cast<int>(kDefaultAudioFrequency *
- audio_clock_drift_ + 0.5);
- int audio_offset = 0;
- int video_frequency = static_cast<int>(kDefaultVideoFrequency *
- video_clock_drift_ + 0.5);
- int video_offset = 0;
- StreamSynchronization::Measurements audio;
- StreamSynchronization::Measurements video;
- // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP.
- audio.rtcp.push_front(send_time_->GenerateRtcp(audio_frequency,
- audio_offset));
- send_time_->IncreaseTimeMs(100);
- receive_time_->IncreaseTimeMs(100);
- video.rtcp.push_front(send_time_->GenerateRtcp(video_frequency,
- video_offset));
- send_time_->IncreaseTimeMs(900);
- receive_time_->IncreaseTimeMs(900);
- audio.rtcp.push_front(send_time_->GenerateRtcp(audio_frequency,
- audio_offset));
- send_time_->IncreaseTimeMs(100);
- receive_time_->IncreaseTimeMs(100);
- video.rtcp.push_front(send_time_->GenerateRtcp(video_frequency,
- video_offset));
- send_time_->IncreaseTimeMs(900);
- receive_time_->IncreaseTimeMs(900);
-
- // Capture an audio and a video frame at the same time.
- audio.latest_timestamp = send_time_->NowRtp(audio_frequency,
- audio_offset);
- video.latest_timestamp = send_time_->NowRtp(video_frequency,
- video_offset);
-
- if (audio_delay_ms > video_delay_ms) {
- // Audio later than video.
- receive_time_->IncreaseTimeMs(video_delay_ms);
- video.latest_receive_time_ms = receive_time_->time_now_ms();
- receive_time_->IncreaseTimeMs(audio_delay_ms - video_delay_ms);
- audio.latest_receive_time_ms = receive_time_->time_now_ms();
- } else {
- // Video later than audio.
- receive_time_->IncreaseTimeMs(audio_delay_ms);
- audio.latest_receive_time_ms = receive_time_->time_now_ms();
- receive_time_->IncreaseTimeMs(video_delay_ms - audio_delay_ms);
- video.latest_receive_time_ms = receive_time_->time_now_ms();
- }
- int relative_delay_ms;
- StreamSynchronization::ComputeRelativeDelay(audio, video,
- &relative_delay_ms);
- EXPECT_EQ(video_delay_ms - audio_delay_ms, relative_delay_ms);
- return sync_->ComputeDelays(relative_delay_ms,
- current_audio_delay_ms,
- extra_audio_delay_ms,
- total_video_delay_ms);
- }
-
- // Simulate audio playback 300 ms after capture and video rendering 100 ms
- // after capture. Verify that the correct extra delays are calculated for
- // audio and video, and that they change correctly when we simulate that
- // NetEQ or the VCM adds more delay to the streams.
- // TODO(holmer): This is currently wrong! We should simply change
- // audio_delay_ms or video_delay_ms since those now include VCM and NetEQ
- // delays.
- void BothDelayedAudioLaterTest(int base_target_delay) {
- int current_audio_delay_ms = base_target_delay;
- int audio_delay_ms = base_target_delay + 300;
- int video_delay_ms = base_target_delay + 100;
- int extra_audio_delay_ms = 0;
- int total_video_delay_ms = base_target_delay;
- int filtered_move = (audio_delay_ms - video_delay_ms) / kSmoothingFilter;
- const int kNeteqDelayIncrease = 50;
- const int kNeteqDelayDecrease = 10;
-
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
- EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
- current_audio_delay_ms = extra_audio_delay_ms;
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
- video_delay_ms));
- // Simulate base_target_delay minimum delay in the VCM.
- total_video_delay_ms = base_target_delay;
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay + 2 * filtered_move, total_video_delay_ms);
- EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
- current_audio_delay_ms = extra_audio_delay_ms;
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
- video_delay_ms));
- // Simulate base_target_delay minimum delay in the VCM.
- total_video_delay_ms = base_target_delay;
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay + 3 * filtered_move, total_video_delay_ms);
- EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
-
- // Simulate that NetEQ introduces some audio delay.
- current_audio_delay_ms = base_target_delay + kNeteqDelayIncrease;
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
- video_delay_ms));
- // Simulate base_target_delay minimum delay in the VCM.
- total_video_delay_ms = base_target_delay;
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- filtered_move = 3 * filtered_move +
- (kNeteqDelayIncrease + audio_delay_ms - video_delay_ms) /
- kSmoothingFilter;
- EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
- EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
-
- // Simulate that NetEQ reduces its delay.
- current_audio_delay_ms = base_target_delay + kNeteqDelayDecrease;
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(1000 - std::max(audio_delay_ms,
- video_delay_ms));
- // Simulate base_target_delay minimum delay in the VCM.
- total_video_delay_ms = base_target_delay;
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
-
- filtered_move = filtered_move +
- (kNeteqDelayDecrease + audio_delay_ms - video_delay_ms) /
- kSmoothingFilter;
-
- EXPECT_EQ(base_target_delay + filtered_move, total_video_delay_ms);
- EXPECT_EQ(base_target_delay, extra_audio_delay_ms);
- }
-
- void BothDelayedVideoLaterTest(int base_target_delay) {
- int current_audio_delay_ms = base_target_delay;
- int audio_delay_ms = base_target_delay + 100;
- int video_delay_ms = base_target_delay + 300;
- int extra_audio_delay_ms = 0;
- int total_video_delay_ms = base_target_delay;
-
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay, total_video_delay_ms);
- // The audio delay is not allowed to change more than this in 1 second.
- EXPECT_GE(base_target_delay + kMaxAudioDiffMs, extra_audio_delay_ms);
- current_audio_delay_ms = extra_audio_delay_ms;
- int current_extra_delay_ms = extra_audio_delay_ms;
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay, total_video_delay_ms);
- // The audio delay is not allowed to change more than the half of the
- // required change in delay.
- EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
- current_audio_delay_ms,
- base_target_delay + video_delay_ms - audio_delay_ms),
- extra_audio_delay_ms);
- current_audio_delay_ms = extra_audio_delay_ms;
- current_extra_delay_ms = extra_audio_delay_ms;
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay, total_video_delay_ms);
- // The audio delay is not allowed to change more than the half of the
- // required change in delay.
- EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
- current_audio_delay_ms,
- base_target_delay + video_delay_ms - audio_delay_ms),
- extra_audio_delay_ms);
- current_extra_delay_ms = extra_audio_delay_ms;
-
- // Simulate that NetEQ for some reason reduced the delay.
- current_audio_delay_ms = base_target_delay + 10;
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay, total_video_delay_ms);
- // Since we only can ask NetEQ for a certain amount of extra delay, and
- // we only measure the total NetEQ delay, we will ask for additional delay
- // here to try to stay in sync.
- EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
- current_audio_delay_ms,
- base_target_delay + video_delay_ms - audio_delay_ms),
- extra_audio_delay_ms);
- current_extra_delay_ms = extra_audio_delay_ms;
-
- // Simulate that NetEQ for some reason significantly increased the delay.
- current_audio_delay_ms = base_target_delay + 350;
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(audio_delay_ms,
- video_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms,
- &total_video_delay_ms));
- EXPECT_EQ(base_target_delay, total_video_delay_ms);
- // The audio delay is not allowed to change more than the half of the
- // required change in delay.
- EXPECT_EQ(current_extra_delay_ms + MaxAudioDelayIncrease(
- current_audio_delay_ms,
- base_target_delay + video_delay_ms - audio_delay_ms),
- extra_audio_delay_ms);
- }
-
- int MaxAudioDelayIncrease(int current_audio_delay_ms, int delay_ms) {
- return std::min((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
- static_cast<int>(kMaxAudioDiffMs));
- }
-
- int MaxAudioDelayDecrease(int current_audio_delay_ms, int delay_ms) {
- return std::max((delay_ms - current_audio_delay_ms) / kSmoothingFilter,
- -kMaxAudioDiffMs);
- }
-
- enum { kSendTimeOffsetMs = 98765 };
- enum { kReceiveTimeOffsetMs = 43210 };
-
- StreamSynchronization* sync_;
- Time* send_time_; // The simulated clock at the sender.
- Time* receive_time_; // The simulated clock at the receiver.
- double audio_clock_drift_;
- double video_clock_drift_;
-};
-
-TEST_F(StreamSynchronizationTest, NoDelay) {
- uint32_t current_audio_delay_ms = 0;
- int extra_audio_delay_ms = 0;
- int total_video_delay_ms = 0;
-
- EXPECT_FALSE(DelayedStreams(0, 0, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, extra_audio_delay_ms);
- EXPECT_EQ(0, total_video_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest, VideoDelay) {
- uint32_t current_audio_delay_ms = 0;
- int delay_ms = 200;
- int extra_audio_delay_ms = 0;
- int total_video_delay_ms = 0;
-
- EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, extra_audio_delay_ms);
- // The video delay is not allowed to change more than this in 1 second.
- EXPECT_EQ(delay_ms / kSmoothingFilter, total_video_delay_ms);
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- // Simulate 0 minimum delay in the VCM.
- total_video_delay_ms = 0;
- EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, extra_audio_delay_ms);
- // The video delay is not allowed to change more than this in 1 second.
- EXPECT_EQ(2 * delay_ms / kSmoothingFilter, total_video_delay_ms);
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- // Simulate 0 minimum delay in the VCM.
- total_video_delay_ms = 0;
- EXPECT_TRUE(DelayedStreams(delay_ms, 0, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, extra_audio_delay_ms);
- EXPECT_EQ(3 * delay_ms / kSmoothingFilter, total_video_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest, AudioDelay) {
- int current_audio_delay_ms = 0;
- int delay_ms = 200;
- int extra_audio_delay_ms = 0;
- int total_video_delay_ms = 0;
-
- EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, total_video_delay_ms);
- // The audio delay is not allowed to change more than this in 1 second.
- EXPECT_EQ(delay_ms / kSmoothingFilter, extra_audio_delay_ms);
- current_audio_delay_ms = extra_audio_delay_ms;
- int current_extra_delay_ms = extra_audio_delay_ms;
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, total_video_delay_ms);
- // The audio delay is not allowed to change more than the half of the required
- // change in delay.
- EXPECT_EQ(current_extra_delay_ms +
- MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
- extra_audio_delay_ms);
- current_audio_delay_ms = extra_audio_delay_ms;
- current_extra_delay_ms = extra_audio_delay_ms;
-
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, total_video_delay_ms);
- // The audio delay is not allowed to change more than the half of the required
- // change in delay.
- EXPECT_EQ(current_extra_delay_ms +
- MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
- extra_audio_delay_ms);
- current_extra_delay_ms = extra_audio_delay_ms;
-
- // Simulate that NetEQ for some reason reduced the delay.
- current_audio_delay_ms = 10;
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, total_video_delay_ms);
- // Since we only can ask NetEQ for a certain amount of extra delay, and
- // we only measure the total NetEQ delay, we will ask for additional delay
- // here to try to
- EXPECT_EQ(current_extra_delay_ms +
- MaxAudioDelayIncrease(current_audio_delay_ms, delay_ms),
- extra_audio_delay_ms);
- current_extra_delay_ms = extra_audio_delay_ms;
-
- // Simulate that NetEQ for some reason significantly increased the delay.
- current_audio_delay_ms = 350;
- send_time_->IncreaseTimeMs(1000);
- receive_time_->IncreaseTimeMs(800);
- EXPECT_TRUE(DelayedStreams(0, delay_ms, current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- EXPECT_EQ(0, total_video_delay_ms);
- // The audio delay is not allowed to change more than the half of the required
- // change in delay.
- EXPECT_EQ(current_extra_delay_ms +
- MaxAudioDelayDecrease(current_audio_delay_ms, delay_ms),
- extra_audio_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) {
- BothDelayedVideoLaterTest(0);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) {
- audio_clock_drift_ = 1.05;
- BothDelayedVideoLaterTest(0);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) {
- video_clock_drift_ = 1.05;
- BothDelayedVideoLaterTest(0);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) {
- BothDelayedAudioLaterTest(0);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) {
- audio_clock_drift_ = 1.05;
- BothDelayedAudioLaterTest(0);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) {
- video_clock_drift_ = 1.05;
- BothDelayedAudioLaterTest(0);
-}
-
-TEST_F(StreamSynchronizationTest, BaseDelay) {
- int base_target_delay_ms = 2000;
- int current_audio_delay_ms = 2000;
- int extra_audio_delay_ms = 0;
- int total_video_delay_ms = base_target_delay_ms;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- // We are in sync don't change.
- EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- // Triggering another call with the same values. Delay should not be modified.
- base_target_delay_ms = 2000;
- current_audio_delay_ms = base_target_delay_ms;
- total_video_delay_ms = base_target_delay_ms;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- // We are in sync don't change.
- EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
- // Changing delay value - intended to test this module only. In practice it
- // would take VoE time to adapt.
- base_target_delay_ms = 5000;
- current_audio_delay_ms = base_target_delay_ms;
- total_video_delay_ms = base_target_delay_ms;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- // We are in sync don't change.
- EXPECT_FALSE(DelayedStreams(base_target_delay_ms, base_target_delay_ms,
- current_audio_delay_ms,
- &extra_audio_delay_ms, &total_video_delay_ms));
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) {
- int base_target_delay_ms = 3000;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- BothDelayedAudioLaterTest(base_target_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) {
- int base_target_delay_ms = 3000;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- audio_clock_drift_ = 1.05;
- BothDelayedAudioLaterTest(base_target_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) {
- int base_target_delay_ms = 3000;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- video_clock_drift_ = 1.05;
- BothDelayedAudioLaterTest(base_target_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) {
- int base_target_delay_ms = 2000;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- BothDelayedVideoLaterTest(base_target_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest,
- BothDelayedVideoLaterAudioClockDriftWithBaseDelay) {
- int base_target_delay_ms = 2000;
- audio_clock_drift_ = 1.05;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- BothDelayedVideoLaterTest(base_target_delay_ms);
-}
-
-TEST_F(StreamSynchronizationTest,
- BothDelayedVideoLaterVideoClockDriftWithBaseDelay) {
- int base_target_delay_ms = 2000;
- video_clock_drift_ = 1.05;
- sync_->SetTargetBufferingDelay(base_target_delay_ms);
- BothDelayedVideoLaterTest(base_target_delay_ms);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/video_engine_core_unittests.gyp b/webrtc/video_engine/video_engine_core_unittests.gyp
deleted file mode 100644
index d0143442b4..0000000000
--- a/webrtc/video_engine/video_engine_core_unittests.gyp
+++ /dev/null
@@ -1,74 +0,0 @@
-# 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.
-
-{
- 'includes': [
- '../build/common.gypi',
- ],
- 'targets': [
- {
- 'target_name': 'video_engine_core_unittests',
- 'type': '<(gtest_target_type)',
- 'dependencies': [
- '<(webrtc_root)/webrtc.gyp:webrtc',
- '<(webrtc_root)/modules/modules.gyp:video_capture_module_internal_impl',
- '<(webrtc_root)/modules/modules.gyp:video_render_module_internal_impl',
- '<(DEPTH)/testing/gtest.gyp:gtest',
- '<(DEPTH)/testing/gmock.gyp:gmock',
- '<(webrtc_root)/test/test.gyp:test_support_main',
- ],
- 'sources': [
- 'call_stats_unittest.cc',
- 'encoder_state_feedback_unittest.cc',
- 'overuse_frame_detector_unittest.cc',
- 'payload_router_unittest.cc',
- 'report_block_stats_unittest.cc',
- 'stream_synchronization_unittest.cc',
- 'vie_codec_unittest.cc',
- 'vie_remb_unittest.cc',
- ],
- 'conditions': [
- ['OS=="android"', {
- 'dependencies': [
- '<(DEPTH)/testing/android/native_test.gyp:native_test_native_code',
- ],
- }],
- ],
- },
- ], # targets
- 'conditions': [
- ['OS=="android"', {
- 'targets': [
- {
- 'target_name': 'video_engine_core_unittests_apk_target',
- 'type': 'none',
- 'dependencies': [
- '<(apk_tests_path):video_engine_core_unittests_apk',
- ],
- },
- ],
- }],
- ['test_isolation_mode != "noop"', {
- 'targets': [
- {
- 'target_name': 'video_engine_core_unittests_run',
- 'type': 'none',
- 'dependencies': [
- 'video_engine_core_unittests',
- ],
- 'includes': [
- '../build/isolate.gypi',
- ],
- 'sources': [
- 'video_engine_core_unittests.isolate',
- ],
- },
- ],
- }],
- ],
-}
diff --git a/webrtc/video_engine/video_engine_core_unittests.isolate b/webrtc/video_engine/video_engine_core_unittests.isolate
deleted file mode 100644
index c8d2fc9026..0000000000
--- a/webrtc/video_engine/video_engine_core_unittests.isolate
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (c) 2013 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.
-{
- 'conditions': [
- ['OS=="linux" or OS=="mac" or OS=="win"', {
- 'variables': {
- 'command': [
- '<(DEPTH)/testing/test_env.py',
- '<(PRODUCT_DIR)/video_engine_core_unittests<(EXECUTABLE_SUFFIX)',
- ],
- 'files': [
- '<(DEPTH)/testing/test_env.py',
- '<(PRODUCT_DIR)/video_engine_core_unittests<(EXECUTABLE_SUFFIX)',
- ],
- },
- }],
- ],
-}
diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc
deleted file mode 100644
index 147ecb1456..0000000000
--- a/webrtc/video_engine/vie_channel.cc
+++ /dev/null
@@ -1,1253 +0,0 @@
-/*
- * 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.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/common.h"
-#include "webrtc/common_video/interface/incoming_video_stream.h"
-#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
-#include "webrtc/frame_callback.h"
-#include "webrtc/modules/pacing/include/paced_sender.h"
-#include "webrtc/modules/pacing/include/packet_router.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/utility/interface/process_thread.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding.h"
-#include "webrtc/modules/video_processing/main/interface/video_processing.h"
-#include "webrtc/modules/video_render/include/video_render_defines.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/metrics.h"
-#include "webrtc/system_wrappers/include/thread_wrapper.h"
-#include "webrtc/video/receive_statistics_proxy.h"
-#include "webrtc/video_engine/call_stats.h"
-#include "webrtc/video_engine/payload_router.h"
-#include "webrtc/video_engine/report_block_stats.h"
-#include "webrtc/video_engine/vie_defines.h"
-
-namespace webrtc {
-
-const int kMaxDecodeWaitTimeMs = 50;
-static const int kMaxTargetDelayMs = 10000;
-static const float kMaxIncompleteTimeMultiplier = 3.5f;
-
-// Helper class receiving statistics callbacks.
-class ChannelStatsObserver : public CallStatsObserver {
- public:
- explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {}
- virtual ~ChannelStatsObserver() {}
-
- // Implements StatsObserver.
- virtual void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
- owner_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
- }
-
- private:
- ViEChannel* const owner_;
-};
-
-class ViEChannelProtectionCallback : public VCMProtectionCallback {
- public:
- ViEChannelProtectionCallback(ViEChannel* owner) : owner_(owner) {}
- ~ViEChannelProtectionCallback() {}
-
-
- int ProtectionRequest(
- const FecProtectionParams* delta_fec_params,
- const FecProtectionParams* key_fec_params,
- uint32_t* sent_video_rate_bps,
- uint32_t* sent_nack_rate_bps,
- uint32_t* sent_fec_rate_bps) override {
- return owner_->ProtectionRequest(delta_fec_params, key_fec_params,
- sent_video_rate_bps, sent_nack_rate_bps,
- sent_fec_rate_bps);
- }
- private:
- ViEChannel* owner_;
-};
-
-ViEChannel::ViEChannel(uint32_t number_of_cores,
- Transport* transport,
- ProcessThread* module_process_thread,
- RtcpIntraFrameObserver* intra_frame_observer,
- RtcpBandwidthObserver* bandwidth_observer,
- TransportFeedbackObserver* transport_feedback_observer,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtcpRttStats* rtt_stats,
- PacedSender* paced_sender,
- PacketRouter* packet_router,
- size_t max_rtp_streams,
- bool sender)
- : number_of_cores_(number_of_cores),
- sender_(sender),
- module_process_thread_(module_process_thread),
- crit_(CriticalSectionWrapper::CreateCriticalSection()),
- send_payload_router_(new PayloadRouter()),
- vcm_protection_callback_(new ViEChannelProtectionCallback(this)),
- vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(),
- nullptr,
- nullptr)),
- vie_receiver_(vcm_, remote_bitrate_estimator, this),
- vie_sync_(vcm_),
- stats_observer_(new ChannelStatsObserver(this)),
- receive_stats_callback_(nullptr),
- incoming_video_stream_(nullptr),
- intra_frame_observer_(intra_frame_observer),
- rtt_stats_(rtt_stats),
- paced_sender_(paced_sender),
- packet_router_(packet_router),
- bandwidth_observer_(bandwidth_observer),
- transport_feedback_observer_(transport_feedback_observer),
- nack_history_size_sender_(kSendSidePacketHistorySize),
- max_nack_reordering_threshold_(kMaxPacketAgeToNack),
- pre_render_callback_(NULL),
- report_block_stats_sender_(new ReportBlockStats()),
- time_of_first_rtt_ms_(-1),
- rtt_sum_ms_(0),
- last_rtt_ms_(0),
- num_rtts_(0),
- rtp_rtcp_modules_(
- CreateRtpRtcpModules(!sender,
- vie_receiver_.GetReceiveStatistics(),
- transport,
- sender ? intra_frame_observer_ : nullptr,
- sender ? bandwidth_observer_.get() : nullptr,
- transport_feedback_observer_,
- rtt_stats_,
- &rtcp_packet_type_counter_observer_,
- remote_bitrate_estimator,
- paced_sender_,
- packet_router_,
- &send_bitrate_observer_,
- &send_frame_count_observer_,
- &send_side_delay_observer_,
- max_rtp_streams)),
- num_active_rtp_rtcp_modules_(1) {
- vie_receiver_.SetRtpRtcpModule(rtp_rtcp_modules_[0]);
- vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
-}
-
-int32_t ViEChannel::Init() {
- module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics());
-
- // RTP/RTCP initialization.
- module_process_thread_->RegisterModule(rtp_rtcp_modules_[0]);
-
- rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
- if (paced_sender_) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
- }
- packet_router_->AddRtpModule(rtp_rtcp_modules_[0]);
- if (sender_) {
- std::list<RtpRtcp*> send_rtp_modules(1, rtp_rtcp_modules_[0]);
- send_payload_router_->SetSendingRtpModules(send_rtp_modules);
- RTC_DCHECK(!send_payload_router_->active());
- }
- if (vcm_->RegisterReceiveCallback(this) != 0) {
- return -1;
- }
- vcm_->RegisterFrameTypeCallback(this);
- vcm_->RegisterReceiveStatisticsCallback(this);
- vcm_->RegisterDecoderTimingCallback(this);
- vcm_->SetRenderDelay(kViEDefaultRenderDelayMs);
-
- module_process_thread_->RegisterModule(vcm_);
- module_process_thread_->RegisterModule(&vie_sync_);
-
- return 0;
-}
-
-ViEChannel::~ViEChannel() {
- UpdateHistograms();
- // Make sure we don't get more callbacks from the RTP module.
- module_process_thread_->DeRegisterModule(
- vie_receiver_.GetReceiveStatistics());
- module_process_thread_->DeRegisterModule(vcm_);
- module_process_thread_->DeRegisterModule(&vie_sync_);
- send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>());
- for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i)
- packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]);
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- module_process_thread_->DeRegisterModule(rtp_rtcp);
- delete rtp_rtcp;
- }
- if (decode_thread_) {
- StopDecodeThread();
- }
- // Release modules.
- VideoCodingModule::Destroy(vcm_);
-}
-
-void ViEChannel::UpdateHistograms() {
- int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds();
-
- {
- CriticalSectionScoped cs(crit_.get());
- int64_t elapsed_sec = (now - time_of_first_rtt_ms_) / 1000;
- if (time_of_first_rtt_ms_ != -1 && num_rtts_ > 0 &&
- elapsed_sec > metrics::kMinRunTimeInSeconds) {
- int64_t avg_rtt_ms = (rtt_sum_ms_ + num_rtts_ / 2) / num_rtts_;
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.AverageRoundTripTimeInMilliseconds", avg_rtt_ms);
- }
- }
-
- if (sender_) {
- RtcpPacketTypeCounter rtcp_counter;
- GetSendRtcpPacketTypeCounter(&rtcp_counter);
- int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000;
- if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsReceivedPerMinute",
- rtcp_counter.nack_packets * 60 / elapsed_sec);
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsReceivedPerMinute",
- rtcp_counter.fir_packets * 60 / elapsed_sec);
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsReceivedPerMinute",
- rtcp_counter.pli_packets * 60 / elapsed_sec);
- if (rtcp_counter.nack_requests > 0) {
- RTC_HISTOGRAM_PERCENTAGE(
- "WebRTC.Video.UniqueNackRequestsReceivedInPercent",
- rtcp_counter.UniqueNackRequestsInPercent());
- }
- int fraction_lost = report_block_stats_sender_->FractionLostInPercent();
- if (fraction_lost != -1) {
- RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.SentPacketsLostInPercent",
- fraction_lost);
- }
- }
-
- StreamDataCounters rtp;
- StreamDataCounters rtx;
- GetSendStreamDataCounters(&rtp, &rtx);
- StreamDataCounters rtp_rtx = rtp;
- rtp_rtx.Add(rtx);
- elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs(
- Clock::GetRealTimeClock()->TimeInMilliseconds()) /
- 1000;
- if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
- RTC_HISTOGRAM_COUNTS_100000(
- "WebRTC.Video.BitrateSentInKbps",
- static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
- 1000));
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.MediaBitrateSentInKbps",
- static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000));
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.PaddingBitrateSentInKbps",
- static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
- 1000));
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.RetransmittedBitrateSentInKbps",
- static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 /
- elapsed_sec / 1000));
- if (rtp_rtcp_modules_[0]->RtxSendStatus() != kRtxOff) {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.RtxBitrateSentInKbps",
- static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
- 1000));
- }
- bool fec_enabled = false;
- uint8_t pltype_red;
- uint8_t pltype_fec;
- rtp_rtcp_modules_[0]->GenericFECStatus(fec_enabled, pltype_red,
- pltype_fec);
- if (fec_enabled) {
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FecBitrateSentInKbps",
- static_cast<int>(rtp_rtx.fec.TotalBytes() *
- 8 / elapsed_sec / 1000));
- }
- }
- } else if (vie_receiver_.GetRemoteSsrc() > 0) {
- // Get receive stats if we are receiving packets, i.e. there is a remote
- // ssrc.
- RtcpPacketTypeCounter rtcp_counter;
- GetReceiveRtcpPacketTypeCounter(&rtcp_counter);
- int64_t elapsed_sec = rtcp_counter.TimeSinceFirstPacketInMs(now) / 1000;
- if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.NackPacketsSentPerMinute",
- rtcp_counter.nack_packets * 60 / elapsed_sec);
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FirPacketsSentPerMinute",
- rtcp_counter.fir_packets * 60 / elapsed_sec);
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute",
- rtcp_counter.pli_packets * 60 / elapsed_sec);
- if (rtcp_counter.nack_requests > 0) {
- RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent",
- rtcp_counter.UniqueNackRequestsInPercent());
- }
- }
-
- StreamDataCounters rtp;
- StreamDataCounters rtx;
- GetReceiveStreamDataCounters(&rtp, &rtx);
- StreamDataCounters rtp_rtx = rtp;
- rtp_rtx.Add(rtx);
- elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs(now) / 1000;
- if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.BitrateReceivedInKbps",
- static_cast<int>(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
- 1000));
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.MediaBitrateReceivedInKbps",
- static_cast<int>(rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000));
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.PaddingBitrateReceivedInKbps",
- static_cast<int>(rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec /
- 1000));
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.RetransmittedBitrateReceivedInKbps",
- static_cast<int>(rtp_rtx.retransmitted.TotalBytes() * 8 /
- elapsed_sec / 1000));
- uint32_t ssrc = 0;
- if (vie_receiver_.GetRtxSsrc(&ssrc)) {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Video.RtxBitrateReceivedInKbps",
- static_cast<int>(rtx.transmitted.TotalBytes() * 8 / elapsed_sec /
- 1000));
- }
- if (vie_receiver_.IsFecEnabled()) {
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.FecBitrateReceivedInKbps",
- static_cast<int>(rtp_rtx.fec.TotalBytes() *
- 8 / elapsed_sec / 1000));
- }
- }
- }
-}
-
-int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
- bool new_stream) {
- RTC_DCHECK(sender_);
- if (video_codec.codecType == kVideoCodecRED ||
- video_codec.codecType == kVideoCodecULPFEC) {
- LOG_F(LS_ERROR) << "Not a valid send codec " << video_codec.codecType;
- return -1;
- }
- if (kMaxSimulcastStreams < video_codec.numberOfSimulcastStreams) {
- LOG_F(LS_ERROR) << "Incorrect config "
- << video_codec.numberOfSimulcastStreams;
- return -1;
- }
- // Update the RTP module with the settings.
- // Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been
- // set explicitly.
- // The first layer is always active, so the first module can be checked for
- // sending status.
- bool is_sending = rtp_rtcp_modules_[0]->Sending();
- bool router_was_active = send_payload_router_->active();
- send_payload_router_->set_active(false);
- send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>());
-
- std::vector<RtpRtcp*> registered_modules;
- std::vector<RtpRtcp*> deregistered_modules;
- size_t num_active_modules = video_codec.numberOfSimulcastStreams > 0
- ? video_codec.numberOfSimulcastStreams
- : 1;
- size_t num_prev_active_modules;
- {
- // Cache which modules are active so StartSend can know which ones to start.
- CriticalSectionScoped cs(crit_.get());
- num_prev_active_modules = num_active_rtp_rtcp_modules_;
- num_active_rtp_rtcp_modules_ = num_active_modules;
- }
- for (size_t i = 0; i < num_active_modules; ++i)
- registered_modules.push_back(rtp_rtcp_modules_[i]);
-
- for (size_t i = num_active_modules; i < rtp_rtcp_modules_.size(); ++i)
- deregistered_modules.push_back(rtp_rtcp_modules_[i]);
-
- // Disable inactive modules.
- for (RtpRtcp* rtp_rtcp : deregistered_modules) {
- rtp_rtcp->SetSendingStatus(false);
- rtp_rtcp->SetSendingMediaStatus(false);
- }
-
- // Configure active modules.
- for (RtpRtcp* rtp_rtcp : registered_modules) {
- rtp_rtcp->DeRegisterSendPayload(video_codec.plType);
- if (rtp_rtcp->RegisterSendPayload(video_codec) != 0) {
- return -1;
- }
- rtp_rtcp->SetSendingStatus(is_sending);
- rtp_rtcp->SetSendingMediaStatus(is_sending);
- }
-
- // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old
- // modules can be deleted after this step.
- vie_receiver_.RegisterRtpRtcpModules(registered_modules);
-
- // Update the packet and payload routers with the sending RtpRtcp modules.
- if (sender_) {
- std::list<RtpRtcp*> active_send_modules;
- for (RtpRtcp* rtp_rtcp : registered_modules)
- active_send_modules.push_back(rtp_rtcp);
- send_payload_router_->SetSendingRtpModules(active_send_modules);
- }
-
- if (router_was_active)
- send_payload_router_->set_active(true);
-
- // Deregister previously registered modules.
- for (size_t i = num_active_modules; i < num_prev_active_modules; ++i) {
- module_process_thread_->DeRegisterModule(rtp_rtcp_modules_[i]);
- packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i]);
- }
- // Register new active modules.
- for (size_t i = num_prev_active_modules; i < num_active_modules; ++i) {
- module_process_thread_->RegisterModule(rtp_rtcp_modules_[i]);
- packet_router_->AddRtpModule(rtp_rtcp_modules_[i]);
- }
- return 0;
-}
-
-int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) {
- RTC_DCHECK(!sender_);
- if (!vie_receiver_.SetReceiveCodec(video_codec)) {
- return -1;
- }
-
- if (video_codec.codecType != kVideoCodecRED &&
- video_codec.codecType != kVideoCodecULPFEC) {
- // Register codec type with VCM, but do not register RED or ULPFEC.
- if (vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_, false) !=
- VCM_OK) {
- return -1;
- }
- }
- return 0;
-}
-
-
-int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type,
- VideoDecoder* decoder,
- bool buffered_rendering,
- int32_t render_delay) {
- RTC_DCHECK(!sender_);
- int32_t result;
- result = vcm_->RegisterExternalDecoder(decoder, pl_type, buffered_rendering);
- if (result != VCM_OK) {
- return result;
- }
- return vcm_->SetRenderDelay(render_delay);
-}
-
-int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) {
- RTC_DCHECK(!sender_);
- VideoCodec current_receive_codec;
- int32_t result = 0;
- result = vcm_->ReceiveCodec(&current_receive_codec);
- if (vcm_->RegisterExternalDecoder(NULL, pl_type, false) != VCM_OK) {
- return -1;
- }
-
- if (result == 0 && current_receive_codec.plType == pl_type) {
- result = vcm_->RegisterReceiveCodec(&current_receive_codec,
- number_of_cores_, false);
- }
- return result;
-}
-
-int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames,
- uint32_t* num_delta_frames) {
- CriticalSectionScoped cs(crit_.get());
- *num_key_frames = receive_frame_counts_.key_frames;
- *num_delta_frames = receive_frame_counts_.delta_frames;
- return 0;
-}
-
-uint32_t ViEChannel::DiscardedPackets() const {
- return vcm_->DiscardedPackets();
-}
-
-int ViEChannel::ReceiveDelay() const {
- return vcm_->Delay();
-}
-
-void ViEChannel::SetRTCPMode(const RtcpMode rtcp_mode) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetRTCPStatus(rtcp_mode);
-}
-
-void ViEChannel::SetProtectionMode(bool enable_nack,
- bool enable_fec,
- int payload_type_red,
- int payload_type_fec) {
- // Validate payload types.
- if (enable_fec) {
- RTC_DCHECK_GE(payload_type_red, 0);
- RTC_DCHECK_GE(payload_type_fec, 0);
- RTC_DCHECK_LE(payload_type_red, 127);
- RTC_DCHECK_LE(payload_type_fec, 127);
- } else {
- RTC_DCHECK_EQ(payload_type_red, -1);
- RTC_DCHECK_EQ(payload_type_fec, -1);
- // Set to valid uint8_ts to be castable later without signed overflows.
- payload_type_red = 0;
- payload_type_fec = 0;
- }
-
- VCMVideoProtection protection_method;
- if (enable_nack) {
- protection_method = enable_fec ? kProtectionNackFEC : kProtectionNack;
- } else {
- protection_method = kProtectionNone;
- }
-
- vcm_->SetVideoProtection(protection_method, true);
-
- // Set NACK.
- ProcessNACKRequest(enable_nack);
-
- // Set FEC.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->SetGenericFECStatus(enable_fec,
- static_cast<uint8_t>(payload_type_red),
- static_cast<uint8_t>(payload_type_fec));
- }
-}
-
-void ViEChannel::ProcessNACKRequest(const bool enable) {
- if (enable) {
- // Turn on NACK.
- if (rtp_rtcp_modules_[0]->RTCP() == RtcpMode::kOff)
- return;
- vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
-
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
-
- vcm_->RegisterPacketRequestCallback(this);
- // Don't introduce errors when NACK is enabled.
- vcm_->SetDecodeErrorMode(kNoErrors);
- } else {
- vcm_->RegisterPacketRequestCallback(NULL);
- if (paced_sender_ == nullptr) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(false, 0);
- }
- vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
- // When NACK is off, allow decoding with errors. Otherwise, the video
- // will freeze, and will only recover with a complete key frame.
- vcm_->SetDecodeErrorMode(kWithErrors);
- }
-}
-
-bool ViEChannel::IsSendingFecEnabled() {
- bool fec_enabled = false;
- uint8_t pltype_red = 0;
- uint8_t pltype_fec = 0;
-
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->GenericFECStatus(fec_enabled, pltype_red, pltype_fec);
- if (fec_enabled)
- return true;
- }
- return false;
-}
-
-int ViEChannel::SetSenderBufferingMode(int target_delay_ms) {
- if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
- LOG(LS_ERROR) << "Invalid send buffer value.";
- return -1;
- }
- if (target_delay_ms == 0) {
- // Real-time mode.
- nack_history_size_sender_ = kSendSidePacketHistorySize;
- } else {
- nack_history_size_sender_ = GetRequiredNackListSize(target_delay_ms);
- // Don't allow a number lower than the default value.
- if (nack_history_size_sender_ < kSendSidePacketHistorySize) {
- nack_history_size_sender_ = kSendSidePacketHistorySize;
- }
- }
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
- return 0;
-}
-
-int ViEChannel::SetReceiverBufferingMode(int target_delay_ms) {
- if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
- LOG(LS_ERROR) << "Invalid receive buffer delay value.";
- return -1;
- }
- int max_nack_list_size;
- int max_incomplete_time_ms;
- if (target_delay_ms == 0) {
- // Real-time mode - restore default settings.
- max_nack_reordering_threshold_ = kMaxPacketAgeToNack;
- max_nack_list_size = kMaxNackListSize;
- max_incomplete_time_ms = 0;
- } else {
- max_nack_list_size = 3 * GetRequiredNackListSize(target_delay_ms) / 4;
- max_nack_reordering_threshold_ = max_nack_list_size;
- // Calculate the max incomplete time and round to int.
- max_incomplete_time_ms = static_cast<int>(kMaxIncompleteTimeMultiplier *
- target_delay_ms + 0.5f);
- }
- vcm_->SetNackSettings(max_nack_list_size, max_nack_reordering_threshold_,
- max_incomplete_time_ms);
- vcm_->SetMinReceiverDelay(target_delay_ms);
- if (vie_sync_.SetTargetBufferingDelay(target_delay_ms) < 0)
- return -1;
- return 0;
-}
-
-int ViEChannel::GetRequiredNackListSize(int target_delay_ms) {
- // The max size of the nack list should be large enough to accommodate the
- // the number of packets (frames) resulting from the increased delay.
- // Roughly estimating for ~40 packets per frame @ 30fps.
- return target_delay_ms * 40 * 30 / 1000;
-}
-
-int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
- // Disable any previous registrations of this extension to avoid errors.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->DeregisterSendRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset);
- }
- if (!enable)
- return 0;
- // Enable the extension.
- int error = 0;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- error |= rtp_rtcp->RegisterSendRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, id);
- }
- return error;
-}
-
-int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
- return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id) ? 0 : -1;
-}
-
-int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) {
- // Disable any previous registrations of this extension to avoid errors.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionAbsoluteSendTime);
- if (!enable)
- return 0;
- // Enable the extension.
- int error = 0;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- error |= rtp_rtcp->RegisterSendRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, id);
- }
- return error;
-}
-
-int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
- return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1;
-}
-
-int ViEChannel::SetSendVideoRotationStatus(bool enable, int id) {
- // Disable any previous registrations of this extension to avoid errors.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
- if (!enable)
- return 0;
- // Enable the extension.
- int error = 0;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- error |= rtp_rtcp->RegisterSendRtpHeaderExtension(
- kRtpExtensionVideoRotation, id);
- }
- return error;
-}
-
-int ViEChannel::SetReceiveVideoRotationStatus(bool enable, int id) {
- return vie_receiver_.SetReceiveVideoRotationStatus(enable, id) ? 0 : -1;
-}
-
-int ViEChannel::SetSendTransportSequenceNumber(bool enable, int id) {
- // Disable any previous registrations of this extension to avoid errors.
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->DeregisterSendRtpHeaderExtension(
- kRtpExtensionTransportSequenceNumber);
- }
- if (!enable)
- return 0;
- // Enable the extension.
- int error = 0;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- error |= rtp_rtcp->RegisterSendRtpHeaderExtension(
- kRtpExtensionTransportSequenceNumber, id);
- }
- return error;
-}
-
-int ViEChannel::SetReceiveTransportSequenceNumber(bool enable, int id) {
- return vie_receiver_.SetReceiveTransportSequenceNumber(enable, id) ? 0 : -1;
-}
-
-void ViEChannel::SetRtcpXrRrtrStatus(bool enable) {
- rtp_rtcp_modules_[0]->SetRtcpXrRrtrStatus(enable);
-}
-
-void ViEChannel::EnableTMMBR(bool enable) {
- rtp_rtcp_modules_[0]->SetTMMBRStatus(enable);
-}
-
-int32_t ViEChannel::SetSSRC(const uint32_t SSRC,
- const StreamType usage,
- const uint8_t simulcast_idx) {
- RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[simulcast_idx];
- if (usage == kViEStreamTypeRtx) {
- rtp_rtcp->SetRtxSsrc(SSRC);
- } else {
- rtp_rtcp->SetSSRC(SSRC);
- }
- return 0;
-}
-
-int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
- const uint32_t SSRC) {
- vie_receiver_.SetRtxSsrc(SSRC);
- return 0;
-}
-
-int32_t ViEChannel::GetLocalSSRC(uint8_t idx, unsigned int* ssrc) {
- RTC_DCHECK_LE(idx, rtp_rtcp_modules_.size());
- *ssrc = rtp_rtcp_modules_[idx]->SSRC();
- return 0;
-}
-
-uint32_t ViEChannel::GetRemoteSSRC() {
- return vie_receiver_.GetRemoteSsrc();
-}
-
-int ViEChannel::SetRtxSendPayloadType(int payload_type,
- int associated_payload_type) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetRtxSendPayloadType(payload_type, associated_payload_type);
- SetRtxSendStatus(true);
- return 0;
-}
-
-void ViEChannel::SetRtxSendStatus(bool enable) {
- int rtx_settings =
- enable ? kRtxRetransmitted | kRtxRedundantPayloads : kRtxOff;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetRtxSendStatus(rtx_settings);
-}
-
-void ViEChannel::SetRtxReceivePayloadType(int payload_type,
- int associated_payload_type) {
- vie_receiver_.SetRtxPayloadType(payload_type, associated_payload_type);
-}
-
-void ViEChannel::SetUseRtxPayloadMappingOnRestore(bool val) {
- vie_receiver_.SetUseRtxPayloadMappingOnRestore(val);
-}
-
-void ViEChannel::SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) {
- RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending());
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- if (rtp_rtcp->SetRtpStateForSsrc(ssrc, rtp_state))
- return;
- }
-}
-
-RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) {
- RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending());
- RtpState rtp_state;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- if (rtp_rtcp->GetRtpStateForSsrc(ssrc, &rtp_state))
- return rtp_state;
- }
- LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc;
- return rtp_state;
-}
-
-// TODO(pbos): Set CNAME on all modules.
-int32_t ViEChannel::SetRTCPCName(const char* rtcp_cname) {
- RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending());
- return rtp_rtcp_modules_[0]->SetCNAME(rtcp_cname);
-}
-
-int32_t ViEChannel::GetRemoteRTCPCName(char rtcp_cname[]) {
- uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
- return rtp_rtcp_modules_[0]->RemoteCNAME(remoteSSRC, rtcp_cname);
-}
-
-int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
- uint32_t* cumulative_lost,
- uint32_t* extended_max,
- uint32_t* jitter_samples,
- int64_t* rtt_ms) {
- // Aggregate the report blocks associated with streams sent on this channel.
- std::vector<RTCPReportBlock> report_blocks;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->RemoteRTCPStat(&report_blocks);
-
- if (report_blocks.empty())
- return -1;
-
- uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
- std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
- for (; it != report_blocks.end(); ++it) {
- if (it->remoteSSRC == remote_ssrc)
- break;
- }
- if (it == report_blocks.end()) {
- // We have not received packets with an SSRC matching the report blocks. To
- // have a chance of calculating an RTT we will try with the SSRC of the
- // first report block received.
- // This is very important for send-only channels where we don't know the
- // SSRC of the other end.
- remote_ssrc = report_blocks[0].remoteSSRC;
- }
-
- // TODO(asapersson): Change report_block_stats to not rely on
- // GetSendRtcpStatistics to be called.
- RTCPReportBlock report =
- report_block_stats_sender_->AggregateAndStore(report_blocks);
- *fraction_lost = report.fractionLost;
- *cumulative_lost = report.cumulativeLost;
- *extended_max = report.extendedHighSeqNum;
- *jitter_samples = report.jitter;
-
- int64_t dummy;
- int64_t rtt = 0;
- if (rtp_rtcp_modules_[0]->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) !=
- 0) {
- return -1;
- }
- *rtt_ms = rtt;
- return 0;
-}
-
-void ViEChannel::RegisterSendChannelRtcpStatisticsCallback(
- RtcpStatisticsCallback* callback) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->RegisterRtcpStatisticsCallback(callback);
-}
-
-void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback(
- RtcpStatisticsCallback* callback) {
- vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
- callback);
- rtp_rtcp_modules_[0]->RegisterRtcpStatisticsCallback(callback);
-}
-
-void ViEChannel::RegisterRtcpPacketTypeCounterObserver(
- RtcpPacketTypeCounterObserver* observer) {
- rtcp_packet_type_counter_observer_.Set(observer);
-}
-
-void ViEChannel::GetSendStreamDataCounters(
- StreamDataCounters* rtp_counters,
- StreamDataCounters* rtx_counters) const {
- *rtp_counters = StreamDataCounters();
- *rtx_counters = StreamDataCounters();
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- StreamDataCounters rtp_data;
- StreamDataCounters rtx_data;
- rtp_rtcp->GetSendStreamDataCounters(&rtp_data, &rtx_data);
- rtp_counters->Add(rtp_data);
- rtx_counters->Add(rtx_data);
- }
-}
-
-void ViEChannel::GetReceiveStreamDataCounters(
- StreamDataCounters* rtp_counters,
- StreamDataCounters* rtx_counters) const {
- StreamStatistician* statistician = vie_receiver_.GetReceiveStatistics()->
- GetStatistician(vie_receiver_.GetRemoteSsrc());
- if (statistician) {
- statistician->GetReceiveStreamDataCounters(rtp_counters);
- }
- uint32_t rtx_ssrc = 0;
- if (vie_receiver_.GetRtxSsrc(&rtx_ssrc)) {
- StreamStatistician* statistician =
- vie_receiver_.GetReceiveStatistics()->GetStatistician(rtx_ssrc);
- if (statistician) {
- statistician->GetReceiveStreamDataCounters(rtx_counters);
- }
- }
-}
-
-void ViEChannel::RegisterSendChannelRtpStatisticsCallback(
- StreamDataCountersCallback* callback) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(callback);
-}
-
-void ViEChannel::RegisterReceiveChannelRtpStatisticsCallback(
- StreamDataCountersCallback* callback) {
- vie_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(callback);
-}
-
-void ViEChannel::GetSendRtcpPacketTypeCounter(
- RtcpPacketTypeCounter* packet_counter) const {
- std::map<uint32_t, RtcpPacketTypeCounter> counter_map =
- rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap();
-
- RtcpPacketTypeCounter counter;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- counter.Add(counter_map[rtp_rtcp->SSRC()]);
- *packet_counter = counter;
-}
-
-void ViEChannel::GetReceiveRtcpPacketTypeCounter(
- RtcpPacketTypeCounter* packet_counter) const {
- std::map<uint32_t, RtcpPacketTypeCounter> counter_map =
- rtcp_packet_type_counter_observer_.GetPacketTypeCounterMap();
-
- RtcpPacketTypeCounter counter;
- counter.Add(counter_map[vie_receiver_.GetRemoteSsrc()]);
-
- *packet_counter = counter;
-}
-
-void ViEChannel::RegisterSendSideDelayObserver(
- SendSideDelayObserver* observer) {
- send_side_delay_observer_.Set(observer);
-}
-
-void ViEChannel::RegisterSendBitrateObserver(
- BitrateStatisticsObserver* observer) {
- send_bitrate_observer_.Set(observer);
-}
-
-int32_t ViEChannel::StartSend() {
- CriticalSectionScoped cs(crit_.get());
-
- if (rtp_rtcp_modules_[0]->Sending())
- return -1;
-
- for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) {
- RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[i];
- rtp_rtcp->SetSendingMediaStatus(true);
- rtp_rtcp->SetSendingStatus(true);
- }
- send_payload_router_->set_active(true);
- return 0;
-}
-
-int32_t ViEChannel::StopSend() {
- send_payload_router_->set_active(false);
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetSendingMediaStatus(false);
-
- if (!rtp_rtcp_modules_[0]->Sending()) {
- return -1;
- }
-
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->SetSendingStatus(false);
- }
- return 0;
-}
-
-bool ViEChannel::Sending() {
- return rtp_rtcp_modules_[0]->Sending();
-}
-
-void ViEChannel::StartReceive() {
- if (!sender_)
- StartDecodeThread();
- vie_receiver_.StartReceive();
-}
-
-void ViEChannel::StopReceive() {
- vie_receiver_.StopReceive();
- if (!sender_) {
- StopDecodeThread();
- vcm_->ResetDecoder();
- }
-}
-
-int32_t ViEChannel::ReceivedRTPPacket(const void* rtp_packet,
- size_t rtp_packet_length,
- const PacketTime& packet_time) {
- return vie_receiver_.ReceivedRTPPacket(
- rtp_packet, rtp_packet_length, packet_time);
-}
-
-int32_t ViEChannel::ReceivedRTCPPacket(const void* rtcp_packet,
- size_t rtcp_packet_length) {
- return vie_receiver_.ReceivedRTCPPacket(rtcp_packet, rtcp_packet_length);
-}
-
-int32_t ViEChannel::SetMTU(uint16_t mtu) {
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
- rtp_rtcp->SetMaxTransferUnit(mtu);
- return 0;
-}
-
-RtpRtcp* ViEChannel::rtp_rtcp() {
- return rtp_rtcp_modules_[0];
-}
-
-rtc::scoped_refptr<PayloadRouter> ViEChannel::send_payload_router() {
- return send_payload_router_;
-}
-
-VCMProtectionCallback* ViEChannel::vcm_protection_callback() {
- return vcm_protection_callback_.get();
-}
-
-CallStatsObserver* ViEChannel::GetStatsObserver() {
- return stats_observer_.get();
-}
-
-// Do not acquire the lock of |vcm_| in this function. Decode callback won't
-// necessarily be called from the decoding thread. The decoding thread may have
-// held the lock when calling VideoDecoder::Decode, Reset, or Release. Acquiring
-// the same lock in the path of decode callback can deadlock.
-int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) { // NOLINT
- CriticalSectionScoped cs(crit_.get());
-
- if (pre_render_callback_ != NULL)
- pre_render_callback_->FrameCallback(&video_frame);
-
- // TODO(pbos): Remove stream id argument.
- incoming_video_stream_->RenderFrame(0xFFFFFFFF, video_frame);
- return 0;
-}
-
-int32_t ViEChannel::ReceivedDecodedReferenceFrame(
- const uint64_t picture_id) {
- return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id);
-}
-
-void ViEChannel::OnIncomingPayloadType(int payload_type) {
- CriticalSectionScoped cs(crit_.get());
- if (receive_stats_callback_)
- receive_stats_callback_->OnIncomingPayloadType(payload_type);
-}
-
-void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) {
- CriticalSectionScoped cs(crit_.get());
- if (receive_stats_callback_)
- receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
-}
-
-void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) {
- CriticalSectionScoped cs(crit_.get());
- if (receive_stats_callback_)
- receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
-}
-
-void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
- CriticalSectionScoped cs(crit_.get());
- receive_frame_counts_ = frame_counts;
- if (receive_stats_callback_)
- receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
-}
-
-void ViEChannel::OnDecoderTiming(int decode_ms,
- int max_decode_ms,
- int current_delay_ms,
- int target_delay_ms,
- int jitter_buffer_ms,
- int min_playout_delay_ms,
- int render_delay_ms) {
- CriticalSectionScoped cs(crit_.get());
- if (!receive_stats_callback_)
- return;
- receive_stats_callback_->OnDecoderTiming(
- decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
- jitter_buffer_ms, min_playout_delay_ms, render_delay_ms, last_rtt_ms_);
-}
-
-int32_t ViEChannel::RequestKeyFrame() {
- return rtp_rtcp_modules_[0]->RequestKeyFrame();
-}
-
-int32_t ViEChannel::SliceLossIndicationRequest(
- const uint64_t picture_id) {
- return rtp_rtcp_modules_[0]->SendRTCPSliceLossIndication(
- static_cast<uint8_t>(picture_id));
-}
-
-int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
- uint16_t length) {
- return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length);
-}
-
-bool ViEChannel::ChannelDecodeThreadFunction(void* obj) {
- return static_cast<ViEChannel*>(obj)->ChannelDecodeProcess();
-}
-
-bool ViEChannel::ChannelDecodeProcess() {
- vcm_->Decode(kMaxDecodeWaitTimeMs);
- return true;
-}
-
-void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
- vcm_->SetReceiveChannelParameters(max_rtt_ms);
-
- CriticalSectionScoped cs(crit_.get());
- if (time_of_first_rtt_ms_ == -1)
- time_of_first_rtt_ms_ = Clock::GetRealTimeClock()->TimeInMilliseconds();
- rtt_sum_ms_ += avg_rtt_ms;
- last_rtt_ms_ = avg_rtt_ms;
- ++num_rtts_;
-}
-
-int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params,
- const FecProtectionParams* key_fec_params,
- uint32_t* video_rate_bps,
- uint32_t* nack_rate_bps,
- uint32_t* fec_rate_bps) {
- *video_rate_bps = 0;
- *nack_rate_bps = 0;
- *fec_rate_bps = 0;
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- uint32_t not_used = 0;
- uint32_t module_video_rate = 0;
- uint32_t module_fec_rate = 0;
- uint32_t module_nack_rate = 0;
- rtp_rtcp->SetFecParameters(delta_fec_params, key_fec_params);
- rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
- &module_nack_rate);
- *video_rate_bps += module_video_rate;
- *nack_rate_bps += module_nack_rate;
- *fec_rate_bps += module_fec_rate;
- }
- return 0;
-}
-
-std::vector<RtpRtcp*> ViEChannel::CreateRtpRtcpModules(
- bool receiver_only,
- ReceiveStatistics* receive_statistics,
- Transport* outgoing_transport,
- RtcpIntraFrameObserver* intra_frame_callback,
- RtcpBandwidthObserver* bandwidth_callback,
- TransportFeedbackObserver* transport_feedback_callback,
- RtcpRttStats* rtt_stats,
- RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtpPacketSender* paced_sender,
- TransportSequenceNumberAllocator* transport_sequence_number_allocator,
- BitrateStatisticsObserver* send_bitrate_observer,
- FrameCountObserver* send_frame_count_observer,
- SendSideDelayObserver* send_side_delay_observer,
- size_t num_modules) {
- RTC_DCHECK_GT(num_modules, 0u);
- RtpRtcp::Configuration configuration;
- ReceiveStatistics* null_receive_statistics = configuration.receive_statistics;
- configuration.audio = false;
- configuration.receiver_only = receiver_only;
- configuration.receive_statistics = receive_statistics;
- configuration.outgoing_transport = outgoing_transport;
- configuration.intra_frame_callback = intra_frame_callback;
- configuration.rtt_stats = rtt_stats;
- configuration.rtcp_packet_type_counter_observer =
- rtcp_packet_type_counter_observer;
- configuration.paced_sender = paced_sender;
- configuration.transport_sequence_number_allocator =
- transport_sequence_number_allocator;
- configuration.send_bitrate_observer = send_bitrate_observer;
- configuration.send_frame_count_observer = send_frame_count_observer;
- configuration.send_side_delay_observer = send_side_delay_observer;
- configuration.bandwidth_callback = bandwidth_callback;
- configuration.transport_feedback_callback = transport_feedback_callback;
-
- std::vector<RtpRtcp*> modules;
- for (size_t i = 0; i < num_modules; ++i) {
- RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
- rtp_rtcp->SetSendingStatus(false);
- rtp_rtcp->SetSendingMediaStatus(false);
- rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
- modules.push_back(rtp_rtcp);
- // Receive statistics and remote bitrate estimator should only be set for
- // the primary (first) module.
- configuration.receive_statistics = null_receive_statistics;
- configuration.remote_bitrate_estimator = nullptr;
- }
- return modules;
-}
-
-void ViEChannel::StartDecodeThread() {
- RTC_DCHECK(!sender_);
- // Start the decode thread
- if (decode_thread_)
- return;
- decode_thread_ = ThreadWrapper::CreateThread(ChannelDecodeThreadFunction,
- this, "DecodingThread");
- decode_thread_->Start();
- decode_thread_->SetPriority(kHighestPriority);
-}
-
-void ViEChannel::StopDecodeThread() {
- if (!decode_thread_)
- return;
-
- vcm_->TriggerDecoderShutdown();
-
- decode_thread_->Stop();
- decode_thread_.reset();
-}
-
-int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id,
- VoEVideoSync* ve_sync_interface) {
- return vie_sync_.ConfigureSync(ve_channel_id, ve_sync_interface,
- rtp_rtcp_modules_[0],
- vie_receiver_.GetRtpReceiver());
-}
-
-int32_t ViEChannel::VoiceChannel() {
- return vie_sync_.VoiceChannel();
-}
-
-void ViEChannel::RegisterPreRenderCallback(
- I420FrameCallback* pre_render_callback) {
- CriticalSectionScoped cs(crit_.get());
- pre_render_callback_ = pre_render_callback;
-}
-
-void ViEChannel::RegisterPreDecodeImageCallback(
- EncodedImageCallback* pre_decode_callback) {
- vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
-}
-
-// TODO(pbos): Remove OnInitializeDecoder which is called from the RTP module,
-// any decoder resetting should be handled internally within the VCM.
-int32_t ViEChannel::OnInitializeDecoder(
- const int8_t payload_type,
- const char payload_name[RTP_PAYLOAD_NAME_SIZE],
- const int frequency,
- const uint8_t channels,
- const uint32_t rate) {
- LOG(LS_INFO) << "OnInitializeDecoder " << static_cast<int>(payload_type)
- << " " << payload_name;
- vcm_->ResetDecoder();
-
- return 0;
-}
-
-void ViEChannel::OnIncomingSSRCChanged(const uint32_t ssrc) {
- rtp_rtcp_modules_[0]->SetRemoteSSRC(ssrc);
-}
-
-void ViEChannel::OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) {}
-
-void ViEChannel::RegisterSendFrameCountObserver(
- FrameCountObserver* observer) {
- send_frame_count_observer_.Set(observer);
-}
-
-void ViEChannel::RegisterReceiveStatisticsProxy(
- ReceiveStatisticsProxy* receive_statistics_proxy) {
- CriticalSectionScoped cs(crit_.get());
- receive_stats_callback_ = receive_statistics_proxy;
-}
-
-void ViEChannel::SetIncomingVideoStream(
- IncomingVideoStream* incoming_video_stream) {
- CriticalSectionScoped cs(crit_.get());
- incoming_video_stream_ = incoming_video_stream;
-}
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h
deleted file mode 100644
index 41c679aafa..0000000000
--- a/webrtc/video_engine/vie_channel.h
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_H_
-#define WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_H_
-
-#include <list>
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/scoped_ref_ptr.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/typedefs.h"
-#include "webrtc/video_engine/vie_defines.h"
-#include "webrtc/video_engine/vie_receiver.h"
-#include "webrtc/video_engine/vie_sync_module.h"
-
-namespace webrtc {
-
-class CallStatsObserver;
-class ChannelStatsObserver;
-class Config;
-class CriticalSectionWrapper;
-class EncodedImageCallback;
-class I420FrameCallback;
-class IncomingVideoStream;
-class PacedSender;
-class PacketRouter;
-class PayloadRouter;
-class ProcessThread;
-class ReceiveStatisticsProxy;
-class ReportBlockStats;
-class RtcpRttStats;
-class ThreadWrapper;
-class ViEChannelProtectionCallback;
-class ViERTPObserver;
-class VideoCodingModule;
-class VideoDecoder;
-class VideoRenderCallback;
-class VoEVideoSync;
-
-enum StreamType {
- kViEStreamTypeNormal = 0, // Normal media stream
- kViEStreamTypeRtx = 1 // Retransmission media stream
-};
-
-class ViEChannel : public VCMFrameTypeCallback,
- public VCMReceiveCallback,
- public VCMReceiveStatisticsCallback,
- public VCMDecoderTimingCallback,
- public VCMPacketRequestCallback,
- public RtpFeedback {
- public:
- friend class ChannelStatsObserver;
- friend class ViEChannelProtectionCallback;
-
- ViEChannel(uint32_t number_of_cores,
- Transport* transport,
- ProcessThread* module_process_thread,
- RtcpIntraFrameObserver* intra_frame_observer,
- RtcpBandwidthObserver* bandwidth_observer,
- TransportFeedbackObserver* transport_feedback_observer,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtcpRttStats* rtt_stats,
- PacedSender* paced_sender,
- PacketRouter* packet_router,
- size_t max_rtp_streams,
- bool sender);
- ~ViEChannel();
-
- int32_t Init();
-
- // Sets the encoder to use for the channel. |new_stream| indicates the encoder
- // type has changed and we should start a new RTP stream.
- int32_t SetSendCodec(const VideoCodec& video_codec, bool new_stream = true);
- int32_t SetReceiveCodec(const VideoCodec& video_codec);
- // Registers an external decoder. |buffered_rendering| means that the decoder
- // will render frames after decoding according to the render timestamp
- // provided by the video coding module. |render_delay| indicates the time
- // needed to decode and render a frame.
- int32_t RegisterExternalDecoder(const uint8_t pl_type,
- VideoDecoder* decoder,
- bool buffered_rendering,
- int32_t render_delay);
- int32_t DeRegisterExternalDecoder(const uint8_t pl_type);
- int32_t ReceiveCodecStatistics(uint32_t* num_key_frames,
- uint32_t* num_delta_frames);
- uint32_t DiscardedPackets() const;
-
- // Returns the estimated delay in milliseconds.
- int ReceiveDelay() const;
-
- void SetRTCPMode(const RtcpMode rtcp_mode);
- void SetProtectionMode(bool enable_nack,
- bool enable_fec,
- int payload_type_red,
- int payload_type_fec);
- bool IsSendingFecEnabled();
- int SetSenderBufferingMode(int target_delay_ms);
- int SetReceiverBufferingMode(int target_delay_ms);
- int SetSendTimestampOffsetStatus(bool enable, int id);
- int SetReceiveTimestampOffsetStatus(bool enable, int id);
- int SetSendAbsoluteSendTimeStatus(bool enable, int id);
- int SetReceiveAbsoluteSendTimeStatus(bool enable, int id);
- int SetSendVideoRotationStatus(bool enable, int id);
- int SetReceiveVideoRotationStatus(bool enable, int id);
- int SetSendTransportSequenceNumber(bool enable, int id);
- int SetReceiveTransportSequenceNumber(bool enable, int id);
- void SetRtcpXrRrtrStatus(bool enable);
- void EnableTMMBR(bool enable);
-
- // Sets SSRC for outgoing stream.
- int32_t SetSSRC(const uint32_t SSRC,
- const StreamType usage,
- const unsigned char simulcast_idx);
-
- // Gets SSRC for outgoing stream number |idx|.
- int32_t GetLocalSSRC(uint8_t idx, unsigned int* ssrc);
-
- // Gets SSRC for the incoming stream.
- uint32_t GetRemoteSSRC();
-
- int SetRtxSendPayloadType(int payload_type, int associated_payload_type);
- void SetRtxReceivePayloadType(int payload_type, int associated_payload_type);
- // If set to true, the RTX payload type mapping supplied in
- // |SetRtxReceivePayloadType| will be used when restoring RTX packets. Without
- // it, RTX packets will always be restored to the last non-RTX packet payload
- // type received.
- void SetUseRtxPayloadMappingOnRestore(bool val);
-
- void SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state);
- RtpState GetRtpStateForSsrc(uint32_t ssrc);
-
- // Sets the CName for the outgoing stream on the channel.
- int32_t SetRTCPCName(const char* rtcp_cname);
-
- // Gets the CName of the incoming stream.
- int32_t GetRemoteRTCPCName(char rtcp_cname[]);
-
- // Returns statistics reported by the remote client in an RTCP packet.
- // TODO(pbos): Remove this along with VideoSendStream::GetRtt().
- int32_t GetSendRtcpStatistics(uint16_t* fraction_lost,
- uint32_t* cumulative_lost,
- uint32_t* extended_max,
- uint32_t* jitter_samples,
- int64_t* rtt_ms);
-
- // Called on receipt of RTCP report block from remote side.
- void RegisterSendChannelRtcpStatisticsCallback(
- RtcpStatisticsCallback* callback);
-
- // Called on generation of RTCP stats
- void RegisterReceiveChannelRtcpStatisticsCallback(
- RtcpStatisticsCallback* callback);
-
- // Gets send statistics for the rtp and rtx stream.
- void GetSendStreamDataCounters(StreamDataCounters* rtp_counters,
- StreamDataCounters* rtx_counters) const;
-
- // Gets received stream data counters.
- void GetReceiveStreamDataCounters(StreamDataCounters* rtp_counters,
- StreamDataCounters* rtx_counters) const;
-
- // Called on update of RTP statistics.
- void RegisterSendChannelRtpStatisticsCallback(
- StreamDataCountersCallback* callback);
-
- // Called on update of RTP statistics.
- void RegisterReceiveChannelRtpStatisticsCallback(
- StreamDataCountersCallback* callback);
-
- void GetSendRtcpPacketTypeCounter(
- RtcpPacketTypeCounter* packet_counter) const;
-
- void GetReceiveRtcpPacketTypeCounter(
- RtcpPacketTypeCounter* packet_counter) const;
-
- void RegisterSendSideDelayObserver(SendSideDelayObserver* observer);
-
- // Called on any new send bitrate estimate.
- void RegisterSendBitrateObserver(BitrateStatisticsObserver* observer);
-
- // Implements RtpFeedback.
- int32_t OnInitializeDecoder(const int8_t payload_type,
- const char payload_name[RTP_PAYLOAD_NAME_SIZE],
- const int frequency,
- const uint8_t channels,
- const uint32_t rate) override;
- void OnIncomingSSRCChanged(const uint32_t ssrc) override;
- void OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) override;
-
- int32_t SetRemoteSSRCType(const StreamType usage, const uint32_t SSRC);
-
- int32_t StartSend();
- int32_t StopSend();
- bool Sending();
- void StartReceive();
- void StopReceive();
-
- int32_t ReceivedRTPPacket(const void* rtp_packet,
- const size_t rtp_packet_length,
- const PacketTime& packet_time);
- int32_t ReceivedRTCPPacket(const void* rtcp_packet,
- const size_t rtcp_packet_length);
-
- // Sets the maximum transfer unit size for the network link, i.e. including
- // IP, UDP and RTP headers.
- int32_t SetMTU(uint16_t mtu);
-
- // Gets the modules used by the channel.
- RtpRtcp* rtp_rtcp();
- rtc::scoped_refptr<PayloadRouter> send_payload_router();
- VCMProtectionCallback* vcm_protection_callback();
-
-
- CallStatsObserver* GetStatsObserver();
-
- // Implements VCMReceiveCallback.
- virtual int32_t FrameToRender(VideoFrame& video_frame); // NOLINT
-
- // Implements VCMReceiveCallback.
- virtual int32_t ReceivedDecodedReferenceFrame(
- const uint64_t picture_id);
-
- // Implements VCMReceiveCallback.
- void OnIncomingPayloadType(int payload_type) override;
-
- // Implements VCMReceiveStatisticsCallback.
- void OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) override;
- void OnDiscardedPacketsUpdated(int discarded_packets) override;
- void OnFrameCountsUpdated(const FrameCounts& frame_counts) override;
-
- // Implements VCMDecoderTimingCallback.
- virtual void OnDecoderTiming(int decode_ms,
- int max_decode_ms,
- int current_delay_ms,
- int target_delay_ms,
- int jitter_buffer_ms,
- int min_playout_delay_ms,
- int render_delay_ms);
-
- // Implements FrameTypeCallback.
- virtual int32_t RequestKeyFrame();
-
- // Implements FrameTypeCallback.
- virtual int32_t SliceLossIndicationRequest(
- const uint64_t picture_id);
-
- // Implements VideoPacketRequestCallback.
- int32_t ResendPackets(const uint16_t* sequence_numbers,
- uint16_t length) override;
-
- int32_t SetVoiceChannel(int32_t ve_channel_id,
- VoEVideoSync* ve_sync_interface);
- int32_t VoiceChannel();
-
- // New-style callbacks, used by VideoReceiveStream.
- void RegisterPreRenderCallback(I420FrameCallback* pre_render_callback);
- void RegisterPreDecodeImageCallback(
- EncodedImageCallback* pre_decode_callback);
-
- void RegisterSendFrameCountObserver(FrameCountObserver* observer);
- void RegisterRtcpPacketTypeCounterObserver(
- RtcpPacketTypeCounterObserver* observer);
- void RegisterReceiveStatisticsProxy(
- ReceiveStatisticsProxy* receive_statistics_proxy);
- void SetIncomingVideoStream(IncomingVideoStream* incoming_video_stream);
-
- protected:
- static bool ChannelDecodeThreadFunction(void* obj);
- bool ChannelDecodeProcess();
-
- void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms);
-
- int ProtectionRequest(const FecProtectionParams* delta_fec_params,
- const FecProtectionParams* key_fec_params,
- uint32_t* sent_video_rate_bps,
- uint32_t* sent_nack_rate_bps,
- uint32_t* sent_fec_rate_bps);
-
- private:
- static std::vector<RtpRtcp*> CreateRtpRtcpModules(
- bool receiver_only,
- ReceiveStatistics* receive_statistics,
- Transport* outgoing_transport,
- RtcpIntraFrameObserver* intra_frame_callback,
- RtcpBandwidthObserver* bandwidth_callback,
- TransportFeedbackObserver* transport_feedback_callback,
- RtcpRttStats* rtt_stats,
- RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtpPacketSender* paced_sender,
- TransportSequenceNumberAllocator* transport_sequence_number_allocator,
- BitrateStatisticsObserver* send_bitrate_observer,
- FrameCountObserver* send_frame_count_observer,
- SendSideDelayObserver* send_side_delay_observer,
- size_t num_modules);
-
- // Assumed to be protected.
- void StartDecodeThread();
- void StopDecodeThread();
-
- void ProcessNACKRequest(const bool enable);
- // Compute NACK list parameters for the buffering mode.
- int GetRequiredNackListSize(int target_delay_ms);
- void SetRtxSendStatus(bool enable);
-
- void UpdateHistograms();
-
- // ViEChannel exposes methods that allow to modify observers and callbacks
- // to be modified. Such an API-style is cumbersome to implement and maintain
- // at all the levels when comparing to only setting them at construction. As
- // so this class instantiates its children with a wrapper that can be modified
- // at a later time.
- template <class T>
- class RegisterableCallback : public T {
- public:
- RegisterableCallback()
- : critsect_(CriticalSectionWrapper::CreateCriticalSection()),
- callback_(NULL) {}
-
- void Set(T* callback) {
- CriticalSectionScoped cs(critsect_.get());
- callback_ = callback;
- }
-
- protected:
- // Note: this should be implemented with a RW-lock to allow simultaneous
- // calls into the callback. However that doesn't seem to be needed for the
- // current type of callbacks covered by this class.
- rtc::scoped_ptr<CriticalSectionWrapper> critsect_;
- T* callback_ GUARDED_BY(critsect_);
-
- private:
- RTC_DISALLOW_COPY_AND_ASSIGN(RegisterableCallback);
- };
-
- class RegisterableBitrateStatisticsObserver:
- public RegisterableCallback<BitrateStatisticsObserver> {
- virtual void Notify(const BitrateStatistics& total_stats,
- const BitrateStatistics& retransmit_stats,
- uint32_t ssrc) {
- CriticalSectionScoped cs(critsect_.get());
- if (callback_)
- callback_->Notify(total_stats, retransmit_stats, ssrc);
- }
- } send_bitrate_observer_;
-
- class RegisterableFrameCountObserver
- : public RegisterableCallback<FrameCountObserver> {
- public:
- virtual void FrameCountUpdated(const FrameCounts& frame_counts,
- uint32_t ssrc) {
- CriticalSectionScoped cs(critsect_.get());
- if (callback_)
- callback_->FrameCountUpdated(frame_counts, ssrc);
- }
-
- private:
- } send_frame_count_observer_;
-
- class RegisterableSendSideDelayObserver :
- public RegisterableCallback<SendSideDelayObserver> {
- void SendSideDelayUpdated(int avg_delay_ms,
- int max_delay_ms,
- uint32_t ssrc) override {
- CriticalSectionScoped cs(critsect_.get());
- if (callback_)
- callback_->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
- }
- } send_side_delay_observer_;
-
- class RegisterableRtcpPacketTypeCounterObserver
- : public RegisterableCallback<RtcpPacketTypeCounterObserver> {
- public:
- void RtcpPacketTypesCounterUpdated(
- uint32_t ssrc,
- const RtcpPacketTypeCounter& packet_counter) override {
- CriticalSectionScoped cs(critsect_.get());
- if (callback_)
- callback_->RtcpPacketTypesCounterUpdated(ssrc, packet_counter);
- counter_map_[ssrc] = packet_counter;
- }
-
- virtual std::map<uint32_t, RtcpPacketTypeCounter> GetPacketTypeCounterMap()
- const {
- CriticalSectionScoped cs(critsect_.get());
- return counter_map_;
- }
-
- private:
- std::map<uint32_t, RtcpPacketTypeCounter> counter_map_
- GUARDED_BY(critsect_);
- } rtcp_packet_type_counter_observer_;
-
- const uint32_t number_of_cores_;
- const bool sender_;
-
- ProcessThread* const module_process_thread_;
-
- // Used for all registered callbacks except rendering.
- rtc::scoped_ptr<CriticalSectionWrapper> crit_;
-
- // Owned modules/classes.
- rtc::scoped_refptr<PayloadRouter> send_payload_router_;
- rtc::scoped_ptr<ViEChannelProtectionCallback> vcm_protection_callback_;
-
- VideoCodingModule* const vcm_;
- ViEReceiver vie_receiver_;
- ViESyncModule vie_sync_;
-
- // Helper to report call statistics.
- rtc::scoped_ptr<ChannelStatsObserver> stats_observer_;
-
- // Not owned.
- ReceiveStatisticsProxy* receive_stats_callback_ GUARDED_BY(crit_);
- FrameCounts receive_frame_counts_ GUARDED_BY(crit_);
- IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_);
- RtcpIntraFrameObserver* const intra_frame_observer_;
- RtcpRttStats* const rtt_stats_;
- PacedSender* const paced_sender_;
- PacketRouter* const packet_router_;
-
- const rtc::scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
- TransportFeedbackObserver* const transport_feedback_observer_;
-
- rtc::scoped_ptr<ThreadWrapper> decode_thread_;
-
- int nack_history_size_sender_;
- int max_nack_reordering_threshold_;
- I420FrameCallback* pre_render_callback_ GUARDED_BY(crit_);
-
- const rtc::scoped_ptr<ReportBlockStats> report_block_stats_sender_;
-
- int64_t time_of_first_rtt_ms_ GUARDED_BY(crit_);
- int64_t rtt_sum_ms_ GUARDED_BY(crit_);
- int64_t last_rtt_ms_ GUARDED_BY(crit_);
- size_t num_rtts_ GUARDED_BY(crit_);
-
- // RtpRtcp modules, declared last as they use other members on construction.
- const std::vector<RtpRtcp*> rtp_rtcp_modules_;
- size_t num_active_rtp_rtcp_modules_ GUARDED_BY(crit_);
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_H_
diff --git a/webrtc/video_engine/vie_codec_unittest.cc b/webrtc/video_engine/vie_codec_unittest.cc
deleted file mode 100644
index 9f648ec521..0000000000
--- a/webrtc/video_engine/vie_codec_unittest.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2014 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 "testing/gtest/include/gtest/gtest.h"
-#include "webrtc/common_types.h"
-
-namespace webrtc {
-
-// Builds VP8 codec with 0 simulcast streams.
-void BuildVP8Codec(webrtc::VideoCodec* video_codec) {
- video_codec->codecType = kVideoCodecVP8;
- strncpy(video_codec->plName, "VP8", 4);
- video_codec->plType = 100;
- video_codec->width = 1280;
- video_codec->height = 720;
-
- video_codec->startBitrate = 1000; // kbps
- video_codec->maxBitrate = 2000; // kbps
- video_codec->minBitrate = 1000; // kbps
- video_codec->maxFramerate = 30;
-
- video_codec->qpMax = 50;
- video_codec->numberOfSimulcastStreams = 0;
- video_codec->mode = kRealtimeVideo;
-
- // Set VP8 codec specific info.
- video_codec->codecSpecific.VP8.pictureLossIndicationOn = true;
- video_codec->codecSpecific.VP8.feedbackModeOn = true;
- video_codec->codecSpecific.VP8.complexity = kComplexityNormal;
- video_codec->codecSpecific.VP8.resilience = kResilienceOff;
- video_codec->codecSpecific.VP8.numberOfTemporalLayers = 0;
- video_codec->codecSpecific.VP8.denoisingOn = true;
- video_codec->codecSpecific.VP8.errorConcealmentOn = true;
- video_codec->codecSpecific.VP8.automaticResizeOn = true;
- video_codec->codecSpecific.VP8.frameDroppingOn = true;
- video_codec->codecSpecific.VP8.keyFrameInterval = 200;
-}
-
-
-void SetSimulcastSettings(webrtc::VideoCodec* video_codec) {
- // Simulcast settings.
- video_codec->numberOfSimulcastStreams = 1;
- video_codec->simulcastStream[0].width = 320;
- video_codec->simulcastStream[0].height = 180;
- video_codec->simulcastStream[0].numberOfTemporalLayers = 0;
- video_codec->simulcastStream[0].maxBitrate = 100;
- video_codec->simulcastStream[0].targetBitrate = 100;
- video_codec->simulcastStream[0].minBitrate = 0;
- video_codec->simulcastStream[0].qpMax = video_codec->qpMax;
-}
-
-
-// This test compares two VideoCodecInst objects except codec specific and
-// simulcast streams.
-TEST(ViECodecTest, TestCompareCodecs) {
- VideoCodec codec1, codec2;
- memset(&codec1, 0, sizeof(VideoCodec));
- memset(&codec2, 0, sizeof(VideoCodec));
-
- BuildVP8Codec(&codec1);
- BuildVP8Codec(&codec2);
-
- EXPECT_TRUE(codec1 == codec2);
- EXPECT_FALSE(codec1 != codec2);
-
- // plname is case insensitive.
- strncpy(codec2.plName, "vp8", 4);
- EXPECT_TRUE(codec1 == codec2);
-
- codec2.codecType = kVideoCodecUnknown;
- EXPECT_FALSE(codec1 == codec2);
-
- // Modify pltype.
- BuildVP8Codec(&codec2);
- codec2.plType = 101;
- EXPECT_FALSE(codec1 == codec2);
-
- // Modifing height and width.
- BuildVP8Codec(&codec2);
- codec2.width = 640;
- codec2.height = 480;
- EXPECT_FALSE(codec1 == codec2);
-
- // Modify framerate, default value is 30.
- BuildVP8Codec(&codec2);
- codec2.maxFramerate = 15;
- EXPECT_FALSE(codec1 == codec2);
-
- // Modifying startBitrate, default value is 1000 kbps.
- BuildVP8Codec(&codec2);
- codec2.startBitrate = 2000;
- EXPECT_FALSE(codec1 == codec2);
- // maxBitrate
- BuildVP8Codec(&codec2);
- codec2.startBitrate = 3000;
- EXPECT_FALSE(codec1 == codec2);
- // minBirate
- BuildVP8Codec(&codec2);
- codec2.startBitrate = 500;
- EXPECT_FALSE(codec1 == codec2);
-
- // Modify qpMax.
- BuildVP8Codec(&codec2);
- codec2.qpMax = 100;
- EXPECT_FALSE(codec1 == codec2);
-
- // Modify mode
- BuildVP8Codec(&codec2);
- codec2.mode = kScreensharing;
- EXPECT_FALSE(codec1 == codec2);
-}
-
-// Test VP8 specific comparision.
-TEST(ViECodecTest, TestCompareVP8CodecSpecific) {
- VideoCodec codec1, codec2;
- memset(&codec1, 0, sizeof(VideoCodec));
- memset(&codec2, 0, sizeof(VideoCodec));
-
- BuildVP8Codec(&codec1);
- BuildVP8Codec(&codec2);
- EXPECT_TRUE(codec1 == codec2);
-
- // pictureLossIndicationOn
- codec2.codecSpecific.VP8.pictureLossIndicationOn = false;
- EXPECT_FALSE(codec1 == codec2);
-
- // feedbackModeOn
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.feedbackModeOn = false;
- EXPECT_FALSE(codec1 == codec2);
-
- // complexity
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.complexity = kComplexityHigh;
- EXPECT_FALSE(codec1 == codec2);
-
- // resilience
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.resilience = kResilientStream;
- EXPECT_FALSE(codec1 == codec2);
-
- // numberOfTemporalLayers
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.numberOfTemporalLayers = 2;
- EXPECT_FALSE(codec1 == codec2);
-
- // denoisingOn
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.denoisingOn = false;
- EXPECT_FALSE(codec1 == codec2);
-
- // errorConcealmentOn
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.errorConcealmentOn = false;
- EXPECT_FALSE(codec1 == codec2);
-
- // pictureLossIndicationOn
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.automaticResizeOn = false;
- EXPECT_FALSE(codec1 == codec2);
-
- // frameDroppingOn
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.frameDroppingOn = false;
- EXPECT_FALSE(codec1 == codec2);
-
- // keyFrameInterval
- BuildVP8Codec(&codec2);
- codec2.codecSpecific.VP8.keyFrameInterval = 100;
- EXPECT_FALSE(codec1 == codec2);
-}
-
-// This test compares simulcast stream information in VideoCodec.
-TEST(ViECodecTest, TestCompareSimulcastStreams) {
- VideoCodec codec1, codec2;
- memset(&codec1, 0, sizeof(VideoCodec));
- memset(&codec2, 0, sizeof(VideoCodec));
-
- BuildVP8Codec(&codec1);
- BuildVP8Codec(&codec2);
- // Set simulacast settings.
- SetSimulcastSettings(&codec1);
- SetSimulcastSettings(&codec2);
- EXPECT_TRUE(codec1 == codec2);
-
- // Modify number of streams.
- codec2.numberOfSimulcastStreams = 2;
- EXPECT_FALSE(codec1 == codec2);
-
- // Resetting steram count.
- codec2.numberOfSimulcastStreams = 1;
- // Modify height and width in codec2.
- codec2.simulcastStream[0].width = 640;
- codec2.simulcastStream[0].height = 480;
- EXPECT_FALSE(codec1 == codec2);
-
- // numberOfTemporalLayers
- SetSimulcastSettings(&codec2);
- codec2.simulcastStream[0].numberOfTemporalLayers = 2;
- EXPECT_FALSE(codec1 == codec2);
-
- // maxBitrate
- SetSimulcastSettings(&codec2);
- codec2.simulcastStream[0].maxBitrate = 1000;
- EXPECT_FALSE(codec1 == codec2);
-
- // targetBitrate
- SetSimulcastSettings(&codec2);
- codec2.simulcastStream[0].targetBitrate = 1000;
- EXPECT_FALSE(codec1 == codec2);
-
- // minBitrate
- SetSimulcastSettings(&codec2);
- codec2.simulcastStream[0].minBitrate = 50;
- EXPECT_FALSE(codec1 == codec2);
-
- // qpMax
- SetSimulcastSettings(&codec2);
- codec2.simulcastStream[0].qpMax = 100;
- EXPECT_FALSE(codec1 == codec2);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_defines.h b/webrtc/video_engine/vie_defines.h
deleted file mode 100644
index 59b56a54fd..0000000000
--- a/webrtc/video_engine/vie_defines.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_VIE_DEFINES_H_
-#define WEBRTC_VIDEO_ENGINE_VIE_DEFINES_H_
-
-#include "webrtc/engine_configurations.h"
-
-// TODO(mflodman) Remove.
-#ifdef WEBRTC_ANDROID
-#include <arpa/inet.h> // NOLINT
-#include <linux/net.h> // NOLINT
-#include <netinet/in.h> // NOLINT
-#include <pthread.h> // NOLINT
-#include <stdio.h> // NOLINT
-#include <stdlib.h> // NOLINT
-#include <string.h> // NOLINT
-#include <sys/socket.h> // NOLINT
-#include <sys/time.h> // NOLINT
-#include <sys/types.h> // NOLINT
-#include <time.h> // NOLINT
-#endif
-
-namespace webrtc {
-
-// General
-enum { kViEMinKeyRequestIntervalMs = 300 };
-
-// ViEBase
-enum { kViEMaxNumberOfChannels = 64 };
-
-// ViECodec
-enum { kViEMaxCodecWidth = 4096 };
-enum { kViEMaxCodecHeight = 3072 };
-enum { kViEMaxCodecFramerate = 60 };
-enum { kViEMinCodecBitrate = 30 };
-
-// ViENetwork
-enum { kViEMaxMtu = 1500 };
-enum { kViESocketThreads = 1 };
-enum { kViENumReceiveSocketBuffers = 500 };
-
-// ViERender
-// Max valid time set in SetRenderTimeoutImage
-enum { kViEMaxRenderTimeoutTimeMs = 10000 };
-// Min valid time set in SetRenderTimeoutImage
-enum { kViEMinRenderTimeoutTimeMs = 33 };
-enum { kViEDefaultRenderDelayMs = 10 };
-
-// ViERTP_RTCP
-enum { kSendSidePacketHistorySize = 600 };
-
-// NACK
-enum { kMaxPacketAgeToNack = 450 }; // In sequence numbers.
-enum { kMaxNackListSize = 250 };
-
-// Id definitions
-enum {
- kViEChannelIdBase = 0x0,
- kViEChannelIdMax = 0xFF,
- kViEDummyChannelId = 0xFFFF
-};
-
-// Module id
-// Create a unique id based on the ViE instance id and the
-// channel id. ViE id > 0 and 0 <= channel id <= 255
-
-inline int ViEId(const int vieId, const int channelId = -1) {
- if (channelId == -1) {
- return static_cast<int>((vieId << 16) + kViEDummyChannelId);
- }
- return static_cast<int>((vieId << 16) + channelId);
-}
-
-inline int ViEModuleId(const int vieId, const int channelId = -1) {
- if (channelId == -1) {
- return static_cast<int>((vieId << 16) + kViEDummyChannelId);
- }
- return static_cast<int>((vieId << 16) + channelId);
-}
-
-inline int ChannelId(const int moduleId) {
- return static_cast<int>(moduleId & 0xffff);
-}
-
-// Windows specific.
-#if defined(_WIN32)
- #define RENDER_MODULE_TYPE kRenderWindows
-
- // Include libraries.
- #pragma comment(lib, "winmm.lib")
-
- #ifndef WEBRTC_EXTERNAL_TRANSPORT
- #pragma comment(lib, "ws2_32.lib")
- #pragma comment(lib, "Iphlpapi.lib") // _GetAdaptersAddresses
- #endif
-#endif
-
-// Mac specific.
-#ifdef WEBRTC_MAC
- #define SLEEP(x) usleep(x * 1000)
- #define RENDER_MODULE_TYPE kRenderWindows
-#endif
-
-// Android specific.
-#ifdef WEBRTC_ANDROID
- #define FAR
- #define __cdecl
-#endif // WEBRTC_ANDROID
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_VIE_DEFINES_H_
diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc
deleted file mode 100644
index 0f4a5a14f5..0000000000
--- a/webrtc/video_engine/vie_encoder.cc
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * 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_encoder.h"
-
-#include <assert.h>
-
-#include <algorithm>
-
-#include "webrtc/base/checks.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/trace_event.h"
-#include "webrtc/common_video/interface/video_image.h"
-#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
-#include "webrtc/frame_callback.h"
-#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
-#include "webrtc/modules/pacing/include/paced_sender.h"
-#include "webrtc/modules/utility/interface/process_thread.h"
-#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
-#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
-#include "webrtc/system_wrappers/include/clock.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/metrics.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/video/send_statistics_proxy.h"
-#include "webrtc/video_engine/payload_router.h"
-#include "webrtc/video_engine/vie_defines.h"
-
-namespace webrtc {
-
-// Margin on when we pause the encoder when the pacing buffer overflows relative
-// to the configured buffer delay.
-static const float kEncoderPausePacerMargin = 2.0f;
-
-// Don't stop the encoder unless the delay is above this configured value.
-static const int kMinPacingDelayMs = 200;
-
-static const float kStopPaddingThresholdMs = 2000;
-
-std::vector<uint32_t> AllocateStreamBitrates(
- uint32_t total_bitrate,
- const SimulcastStream* stream_configs,
- size_t number_of_streams) {
- if (number_of_streams == 0) {
- std::vector<uint32_t> stream_bitrates(1, 0);
- stream_bitrates[0] = total_bitrate;
- return stream_bitrates;
- }
- std::vector<uint32_t> stream_bitrates(number_of_streams, 0);
- uint32_t bitrate_remainder = total_bitrate;
- for (size_t i = 0; i < stream_bitrates.size() && bitrate_remainder > 0; ++i) {
- if (stream_configs[i].maxBitrate * 1000 > bitrate_remainder) {
- stream_bitrates[i] = bitrate_remainder;
- } else {
- stream_bitrates[i] = stream_configs[i].maxBitrate * 1000;
- }
- bitrate_remainder -= stream_bitrates[i];
- }
- return stream_bitrates;
-}
-
-class QMVideoSettingsCallback : public VCMQMSettingsCallback {
- public:
- explicit QMVideoSettingsCallback(VideoProcessingModule* vpm);
-
- ~QMVideoSettingsCallback();
-
- // Update VPM with QM (quality modes: frame size & frame rate) settings.
- int32_t SetVideoQMSettings(const uint32_t frame_rate,
- const uint32_t width,
- const uint32_t height);
-
- // Update target frame rate.
- void SetTargetFramerate(int frame_rate);
-
- private:
- VideoProcessingModule* vpm_;
-};
-
-class ViEBitrateObserver : public BitrateObserver {
- public:
- explicit ViEBitrateObserver(ViEEncoder* owner)
- : owner_(owner) {
- }
- virtual ~ViEBitrateObserver() {}
- // Implements BitrateObserver.
- virtual void OnNetworkChanged(uint32_t bitrate_bps,
- uint8_t fraction_lost,
- int64_t rtt) {
- owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt);
- }
- private:
- ViEEncoder* owner_;
-};
-
-ViEEncoder::ViEEncoder(uint32_t number_of_cores,
- ProcessThread* module_process_thread,
- SendStatisticsProxy* stats_proxy,
- I420FrameCallback* pre_encode_callback,
- PacedSender* pacer,
- BitrateAllocator* bitrate_allocator)
- : number_of_cores_(number_of_cores),
- vpm_(VideoProcessingModule::Create()),
- qm_callback_(new QMVideoSettingsCallback(vpm_.get())),
- vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(),
- this,
- qm_callback_.get())),
- send_payload_router_(NULL),
- data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
- stats_proxy_(stats_proxy),
- pre_encode_callback_(pre_encode_callback),
- pacer_(pacer),
- bitrate_allocator_(bitrate_allocator),
- time_of_last_frame_activity_ms_(0),
- simulcast_enabled_(false),
- min_transmit_bitrate_kbps_(0),
- last_observed_bitrate_bps_(0),
- target_delay_ms_(0),
- network_is_transmitting_(true),
- encoder_paused_(false),
- encoder_paused_and_dropped_frame_(false),
- fec_enabled_(false),
- nack_enabled_(false),
- module_process_thread_(module_process_thread),
- has_received_sli_(false),
- picture_id_sli_(0),
- has_received_rpsi_(false),
- picture_id_rpsi_(0),
- video_suspended_(false) {
- bitrate_observer_.reset(new ViEBitrateObserver(this));
-}
-
-bool ViEEncoder::Init() {
- vpm_->EnableTemporalDecimation(true);
-
- // Enable/disable content analysis: off by default for now.
- vpm_->EnableContentAnalysis(false);
-
- if (vcm_->RegisterTransportCallback(this) != 0) {
- return false;
- }
- if (vcm_->RegisterSendStatisticsCallback(this) != 0) {
- return false;
- }
- return true;
-}
-
-void ViEEncoder::StartThreadsAndSetSharedMembers(
- rtc::scoped_refptr<PayloadRouter> send_payload_router,
- VCMProtectionCallback* vcm_protection_callback) {
- RTC_DCHECK(send_payload_router_ == NULL);
-
- send_payload_router_ = send_payload_router;
- vcm_->RegisterProtectionCallback(vcm_protection_callback);
- module_process_thread_->RegisterModule(vcm_.get());
-}
-
-void ViEEncoder::StopThreadsAndRemoveSharedMembers() {
- if (bitrate_allocator_)
- bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get());
- module_process_thread_->DeRegisterModule(vcm_.get());
- module_process_thread_->DeRegisterModule(vpm_.get());
-}
-
-ViEEncoder::~ViEEncoder() {
-}
-
-void ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) {
- {
- CriticalSectionScoped cs(data_cs_.get());
- network_is_transmitting_ = is_transmitting;
- }
-}
-
-void ViEEncoder::Pause() {
- CriticalSectionScoped cs(data_cs_.get());
- encoder_paused_ = true;
-}
-
-void ViEEncoder::Restart() {
- CriticalSectionScoped cs(data_cs_.get());
- encoder_paused_ = false;
-}
-
-uint8_t ViEEncoder::NumberOfCodecs() {
- return vcm_->NumberOfCodecs();
-}
-
-int32_t ViEEncoder::GetCodec(uint8_t list_index, VideoCodec* video_codec) {
- if (vcm_->Codec(list_index, video_codec) != 0) {
- return -1;
- }
- return 0;
-}
-
-int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder,
- uint8_t pl_type,
- bool internal_source) {
- if (encoder == NULL)
- return -1;
-
- if (vcm_->RegisterExternalEncoder(encoder, pl_type, internal_source) !=
- VCM_OK) {
- return -1;
- }
- return 0;
-}
-
-int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) {
- if (vcm_->RegisterExternalEncoder(NULL, pl_type) != VCM_OK) {
- return -1;
- }
- return 0;
-}
-
-int32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) {
- RTC_DCHECK(send_payload_router_ != NULL);
- // Setting target width and height for VPM.
- if (vpm_->SetTargetResolution(video_codec.width, video_codec.height,
- video_codec.maxFramerate) != VPM_OK) {
- return -1;
- }
-
- {
- CriticalSectionScoped cs(data_cs_.get());
- simulcast_enabled_ = video_codec.numberOfSimulcastStreams > 1;
- }
-
- // Add a bitrate observer to the allocator and update the start, max and
- // min bitrates of the bitrate controller as needed.
- int allocated_bitrate_bps = bitrate_allocator_->AddBitrateObserver(
- bitrate_observer_.get(), video_codec.minBitrate * 1000,
- video_codec.maxBitrate * 1000);
-
- webrtc::VideoCodec modified_video_codec = video_codec;
- modified_video_codec.startBitrate = allocated_bitrate_bps / 1000;
-
- size_t max_data_payload_length = send_payload_router_->MaxPayloadLength();
- if (vcm_->RegisterSendCodec(&modified_video_codec, number_of_cores_,
- static_cast<uint32_t>(max_data_payload_length)) !=
- VCM_OK) {
- return -1;
- }
- return 0;
-}
-
-int32_t ViEEncoder::GetEncoder(VideoCodec* video_codec) {
- *video_codec = vcm_->GetSendCodec();
- return 0;
-}
-
-int32_t ViEEncoder::ScaleInputImage(bool enable) {
- VideoFrameResampling resampling_mode = kFastRescaling;
- // TODO(mflodman) What?
- if (enable) {
- // kInterpolation is currently not supported.
- LOG_F(LS_ERROR) << "Not supported.";
- return -1;
- }
- vpm_->SetInputFrameResampleMode(resampling_mode);
-
- return 0;
-}
-
-int ViEEncoder::GetPaddingNeededBps() const {
- int64_t time_of_last_frame_activity_ms;
- int min_transmit_bitrate_bps;
- int bitrate_bps;
- {
- CriticalSectionScoped cs(data_cs_.get());
- bool send_padding = simulcast_enabled_ || video_suspended_ ||
- min_transmit_bitrate_kbps_ > 0;
- if (!send_padding)
- return 0;
- time_of_last_frame_activity_ms = time_of_last_frame_activity_ms_;
- min_transmit_bitrate_bps = 1000 * min_transmit_bitrate_kbps_;
- bitrate_bps = last_observed_bitrate_bps_;
- }
-
- VideoCodec send_codec;
- if (vcm_->SendCodec(&send_codec) != 0)
- return 0;
-
- bool video_is_suspended = vcm_->VideoSuspended();
-
- // Find the max amount of padding we can allow ourselves to send at this
- // point, based on which streams are currently active and what our current
- // available bandwidth is.
- int pad_up_to_bitrate_bps = 0;
- if (send_codec.numberOfSimulcastStreams == 0) {
- pad_up_to_bitrate_bps = send_codec.minBitrate * 1000;
- } else {
- SimulcastStream* stream_configs = send_codec.simulcastStream;
- pad_up_to_bitrate_bps =
- stream_configs[send_codec.numberOfSimulcastStreams - 1].minBitrate *
- 1000;
- for (int i = 0; i < send_codec.numberOfSimulcastStreams - 1; ++i) {
- pad_up_to_bitrate_bps += stream_configs[i].targetBitrate * 1000;
- }
- }
-
- // Disable padding if only sending one stream and video isn't suspended and
- // min-transmit bitrate isn't used (applied later).
- if (!video_is_suspended && send_codec.numberOfSimulcastStreams <= 1)
- pad_up_to_bitrate_bps = 0;
-
- // The amount of padding should decay to zero if no frames are being
- // captured/encoded unless a min-transmit bitrate is used.
- int64_t now_ms = TickTime::MillisecondTimestamp();
- if (now_ms - time_of_last_frame_activity_ms > kStopPaddingThresholdMs)
- pad_up_to_bitrate_bps = 0;
-
- // Pad up to min bitrate.
- if (pad_up_to_bitrate_bps < min_transmit_bitrate_bps)
- pad_up_to_bitrate_bps = min_transmit_bitrate_bps;
-
- // Padding may never exceed bitrate estimate.
- if (pad_up_to_bitrate_bps > bitrate_bps)
- pad_up_to_bitrate_bps = bitrate_bps;
-
- return pad_up_to_bitrate_bps;
-}
-
-bool ViEEncoder::EncoderPaused() const {
- // Pause video if paused by caller or as long as the network is down or the
- // pacer queue has grown too large in buffered mode.
- if (encoder_paused_) {
- return true;
- }
- if (target_delay_ms_ > 0) {
- // Buffered mode.
- // TODO(pwestin): Workaround until nack is configured as a time and not
- // number of packets.
- return pacer_->QueueInMs() >=
- std::max(
- static_cast<int>(target_delay_ms_ * kEncoderPausePacerMargin),
- kMinPacingDelayMs);
- }
- if (pacer_->ExpectedQueueTimeMs() > PacedSender::kDefaultMaxQueueLengthMs) {
- // Too much data in pacer queue, drop frame.
- return true;
- }
- return !network_is_transmitting_;
-}
-
-void ViEEncoder::TraceFrameDropStart() {
- // Start trace event only on the first frame after encoder is paused.
- if (!encoder_paused_and_dropped_frame_) {
- TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
- }
- encoder_paused_and_dropped_frame_ = true;
- return;
-}
-
-void ViEEncoder::TraceFrameDropEnd() {
- // End trace event on first frame after encoder resumes, if frame was dropped.
- if (encoder_paused_and_dropped_frame_) {
- TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
- }
- encoder_paused_and_dropped_frame_ = false;
-}
-
-void ViEEncoder::DeliverFrame(VideoFrame video_frame) {
- RTC_DCHECK(send_payload_router_ != NULL);
- if (!send_payload_router_->active()) {
- // We've paused or we have no channels attached, don't waste resources on
- // encoding.
- return;
- }
- {
- CriticalSectionScoped cs(data_cs_.get());
- time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp();
- if (EncoderPaused()) {
- TraceFrameDropStart();
- return;
- }
- TraceFrameDropEnd();
- }
-
- TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
- "Encode");
- VideoFrame* decimated_frame = NULL;
- // TODO(wuchengli): support texture frames.
- if (video_frame.native_handle() == NULL) {
- // Pass frame via preprocessor.
- const int ret = vpm_->PreprocessFrame(video_frame, &decimated_frame);
- if (ret == 1) {
- // Drop this frame.
- return;
- }
- if (ret != VPM_OK) {
- return;
- }
- }
-
- // If we haven't resampled the frame and we have a FrameCallback, we need to
- // make a deep copy of |video_frame|.
- VideoFrame copied_frame;
- if (pre_encode_callback_) {
- // If the frame was not resampled or scaled => use copy of original.
- if (decimated_frame == NULL) {
- copied_frame.CopyFrame(video_frame);
- decimated_frame = &copied_frame;
- }
- pre_encode_callback_->FrameCallback(decimated_frame);
- }
-
- // If the frame was not resampled, scaled, or touched by FrameCallback => use
- // original. The frame is const from here.
- const VideoFrame* output_frame =
- (decimated_frame != NULL) ? decimated_frame : &video_frame;
-
-#ifdef VIDEOCODEC_VP8
- if (vcm_->SendCodec() == webrtc::kVideoCodecVP8) {
- webrtc::CodecSpecificInfo codec_specific_info;
- codec_specific_info.codecType = webrtc::kVideoCodecVP8;
- {
- CriticalSectionScoped cs(data_cs_.get());
- codec_specific_info.codecSpecific.VP8.hasReceivedRPSI =
- has_received_rpsi_;
- codec_specific_info.codecSpecific.VP8.hasReceivedSLI =
- has_received_sli_;
- codec_specific_info.codecSpecific.VP8.pictureIdRPSI =
- picture_id_rpsi_;
- codec_specific_info.codecSpecific.VP8.pictureIdSLI =
- picture_id_sli_;
- has_received_sli_ = false;
- has_received_rpsi_ = false;
- }
-
- vcm_->AddVideoFrame(*output_frame, vpm_->ContentMetrics(),
- &codec_specific_info);
- return;
- }
-#endif
- vcm_->AddVideoFrame(*output_frame);
-}
-
-int ViEEncoder::SendKeyFrame() {
- return vcm_->IntraFrameRequest(0);
-}
-
-uint32_t ViEEncoder::LastObservedBitrateBps() const {
- CriticalSectionScoped cs(data_cs_.get());
- return last_observed_bitrate_bps_;
-}
-
-int ViEEncoder::CodecTargetBitrate(uint32_t* bitrate) const {
- if (vcm_->Bitrate(bitrate) != 0)
- return -1;
- return 0;
-}
-
-int32_t ViEEncoder::UpdateProtectionMethod(bool nack, bool fec) {
- RTC_DCHECK(send_payload_router_ != NULL);
-
- if (fec_enabled_ == fec && nack_enabled_ == nack) {
- // No change needed, we're already in correct state.
- return 0;
- }
- fec_enabled_ = fec;
- nack_enabled_ = nack;
-
- // Set Video Protection for VCM.
- VCMVideoProtection protection_mode;
- if (fec_enabled_) {
- protection_mode =
- nack_enabled_ ? webrtc::kProtectionNackFEC : kProtectionFEC;
- } else {
- protection_mode = nack_enabled_ ? kProtectionNack : kProtectionNone;
- }
- vcm_->SetVideoProtection(protection_mode, true);
-
- if (fec_enabled_ || nack_enabled_) {
- // The send codec must be registered to set correct MTU.
- webrtc::VideoCodec codec;
- if (vcm_->SendCodec(&codec) == 0) {
- uint32_t current_bitrate_bps = 0;
- if (vcm_->Bitrate(&current_bitrate_bps) != 0) {
- LOG_F(LS_WARNING) <<
- "Failed to get the current encoder target bitrate.";
- }
- // Convert to start bitrate in kbps.
- codec.startBitrate = (current_bitrate_bps + 500) / 1000;
- size_t max_payload_length = send_payload_router_->MaxPayloadLength();
- if (vcm_->RegisterSendCodec(&codec, number_of_cores_,
- static_cast<uint32_t>(max_payload_length)) !=
- 0) {
- return -1;
- }
- }
- }
- return 0;
-}
-
-void ViEEncoder::SetSenderBufferingMode(int target_delay_ms) {
- {
- CriticalSectionScoped cs(data_cs_.get());
- target_delay_ms_ = target_delay_ms;
- }
- if (target_delay_ms > 0) {
- // Disable external frame-droppers.
- vcm_->EnableFrameDropper(false);
- vpm_->EnableTemporalDecimation(false);
- } else {
- // Real-time mode - enable frame droppers.
- vpm_->EnableTemporalDecimation(true);
- vcm_->EnableFrameDropper(true);
- }
-}
-
-void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) {
- if (stats_proxy_)
- stats_proxy_->OnSetRates(bitrate_bps, framerate);
-}
-
-int32_t ViEEncoder::SendData(
- const uint8_t payload_type,
- const EncodedImage& encoded_image,
- const webrtc::RTPFragmentationHeader& fragmentation_header,
- const RTPVideoHeader* rtp_video_hdr) {
- RTC_DCHECK(send_payload_router_ != NULL);
-
- {
- CriticalSectionScoped cs(data_cs_.get());
- time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp();
- }
-
- if (stats_proxy_ != NULL)
- stats_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr);
-
- return send_payload_router_->RoutePayload(
- encoded_image._frameType, payload_type, encoded_image._timeStamp,
- encoded_image.capture_time_ms_, encoded_image._buffer,
- encoded_image._length, &fragmentation_header, rtp_video_hdr)
- ? 0
- : -1;
-}
-
-int32_t ViEEncoder::SendStatistics(const uint32_t bit_rate,
- const uint32_t frame_rate) {
- if (stats_proxy_)
- stats_proxy_->OnOutgoingRate(frame_rate, bit_rate);
- return 0;
-}
-
-void ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/,
- uint8_t picture_id) {
- CriticalSectionScoped cs(data_cs_.get());
- picture_id_sli_ = picture_id;
- has_received_sli_ = true;
-}
-
-void ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/,
- uint64_t picture_id) {
- CriticalSectionScoped cs(data_cs_.get());
- picture_id_rpsi_ = picture_id;
- has_received_rpsi_ = true;
-}
-
-void ViEEncoder::OnReceivedIntraFrameRequest(uint32_t ssrc) {
- // Key frame request from remote side, signal to VCM.
- TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
-
- int idx = 0;
- {
- CriticalSectionScoped cs(data_cs_.get());
- auto stream_it = ssrc_streams_.find(ssrc);
- if (stream_it == ssrc_streams_.end()) {
- LOG_F(LS_WARNING) << "ssrc not found: " << ssrc << ", map size "
- << ssrc_streams_.size();
- return;
- }
- std::map<unsigned int, int64_t>::iterator time_it =
- time_last_intra_request_ms_.find(ssrc);
- if (time_it == time_last_intra_request_ms_.end()) {
- time_last_intra_request_ms_[ssrc] = 0;
- }
-
- int64_t now = TickTime::MillisecondTimestamp();
- if (time_last_intra_request_ms_[ssrc] + kViEMinKeyRequestIntervalMs > now) {
- return;
- }
- time_last_intra_request_ms_[ssrc] = now;
- idx = stream_it->second;
- }
- // Release the critsect before triggering key frame.
- vcm_->IntraFrameRequest(idx);
-}
-
-void ViEEncoder::OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {
- CriticalSectionScoped cs(data_cs_.get());
- std::map<unsigned int, int>::iterator it = ssrc_streams_.find(old_ssrc);
- if (it == ssrc_streams_.end()) {
- return;
- }
-
- ssrc_streams_[new_ssrc] = it->second;
- ssrc_streams_.erase(it);
-
- std::map<unsigned int, int64_t>::iterator time_it =
- time_last_intra_request_ms_.find(old_ssrc);
- int64_t last_intra_request_ms = 0;
- if (time_it != time_last_intra_request_ms_.end()) {
- last_intra_request_ms = time_it->second;
- time_last_intra_request_ms_.erase(time_it);
- }
- time_last_intra_request_ms_[new_ssrc] = last_intra_request_ms;
-}
-
-bool ViEEncoder::SetSsrcs(const std::vector<uint32_t>& ssrcs) {
- VideoCodec codec;
- if (vcm_->SendCodec(&codec) != 0)
- return false;
-
- if (codec.numberOfSimulcastStreams > 0 &&
- ssrcs.size() != codec.numberOfSimulcastStreams) {
- return false;
- }
-
- CriticalSectionScoped cs(data_cs_.get());
- ssrc_streams_.clear();
- time_last_intra_request_ms_.clear();
- int idx = 0;
- for (uint32_t ssrc : ssrcs) {
- ssrc_streams_[ssrc] = idx++;
- }
- return true;
-}
-
-void ViEEncoder::SetMinTransmitBitrate(int min_transmit_bitrate_kbps) {
- assert(min_transmit_bitrate_kbps >= 0);
- CriticalSectionScoped crit(data_cs_.get());
- min_transmit_bitrate_kbps_ = min_transmit_bitrate_kbps;
-}
-
-// Called from ViEBitrateObserver.
-void ViEEncoder::OnNetworkChanged(uint32_t bitrate_bps,
- uint8_t fraction_lost,
- int64_t round_trip_time_ms) {
- LOG(LS_VERBOSE) << "OnNetworkChanged, bitrate" << bitrate_bps
- << " packet loss " << static_cast<int>(fraction_lost)
- << " rtt " << round_trip_time_ms;
- RTC_DCHECK(send_payload_router_ != NULL);
- vcm_->SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms);
- bool video_is_suspended = vcm_->VideoSuspended();
-
- VideoCodec send_codec;
- if (vcm_->SendCodec(&send_codec) != 0) {
- return;
- }
- SimulcastStream* stream_configs = send_codec.simulcastStream;
- // Allocate the bandwidth between the streams.
- std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates(
- bitrate_bps, stream_configs, send_codec.numberOfSimulcastStreams);
- send_payload_router_->SetTargetSendBitrates(stream_bitrates);
-
- {
- CriticalSectionScoped cs(data_cs_.get());
- last_observed_bitrate_bps_ = bitrate_bps;
- if (video_suspended_ == video_is_suspended)
- return;
- video_suspended_ = video_is_suspended;
-
- LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended
- << " for ssrc " << ssrc_streams_.begin()->first;
- }
- // Video suspend-state changed, inform codec observer.
- if (stats_proxy_)
- stats_proxy_->OnSuspendChange(video_is_suspended);
-}
-
-void ViEEncoder::SuspendBelowMinBitrate() {
- vcm_->SuspendBelowMinBitrate();
- bitrate_allocator_->EnforceMinBitrate(false);
-}
-
-void ViEEncoder::RegisterPostEncodeImageCallback(
- EncodedImageCallback* post_encode_callback) {
- vcm_->RegisterPostEncodeImageCallback(post_encode_callback);
-}
-
-QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm)
- : vpm_(vpm) {
-}
-
-QMVideoSettingsCallback::~QMVideoSettingsCallback() {
-}
-
-int32_t QMVideoSettingsCallback::SetVideoQMSettings(
- const uint32_t frame_rate,
- const uint32_t width,
- const uint32_t height) {
- return vpm_->SetTargetResolution(width, height, frame_rate);
-}
-
-void QMVideoSettingsCallback::SetTargetFramerate(int frame_rate) {
- vpm_->SetTargetFramerate(frame_rate);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h
deleted file mode 100644
index 54aacdbfa9..0000000000
--- a/webrtc/video_engine/vie_encoder.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_VIE_ENCODER_H_
-#define WEBRTC_VIDEO_ENGINE_VIE_ENCODER_H_
-
-#include <map>
-#include <vector>
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/scoped_ref_ptr.h"
-#include "webrtc/base/thread_annotations.h"
-#include "webrtc/common_types.h"
-#include "webrtc/frame_callback.h"
-#include "webrtc/modules/bitrate_controller/include/bitrate_allocator.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
-#include "webrtc/modules/video_processing/main/interface/video_processing.h"
-#include "webrtc/typedefs.h"
-#include "webrtc/video/video_capture_input.h"
-#include "webrtc/video_engine/vie_defines.h"
-
-namespace webrtc {
-
-class Config;
-class CriticalSectionWrapper;
-class EncodedImageCallback;
-class PacedSender;
-class PayloadRouter;
-class ProcessThread;
-class QMVideoSettingsCallback;
-class SendStatisticsProxy;
-class ViEBitrateObserver;
-class ViEEffectFilter;
-class VideoCodingModule;
-
-class ViEEncoder : public RtcpIntraFrameObserver,
- public VideoEncoderRateObserver,
- public VCMPacketizationCallback,
- public VCMSendStatisticsCallback,
- public VideoCaptureCallback {
- public:
- friend class ViEBitrateObserver;
-
- ViEEncoder(uint32_t number_of_cores,
- ProcessThread* module_process_thread,
- SendStatisticsProxy* stats_proxy,
- I420FrameCallback* pre_encode_callback,
- PacedSender* pacer,
- BitrateAllocator* bitrate_allocator);
- ~ViEEncoder();
-
- bool Init();
-
- // This function is assumed to be called before any frames are delivered and
- // only once.
- // Ideally this would be done in Init, but the dependencies between ViEEncoder
- // and ViEChannel makes it really hard to do in a good way.
- void StartThreadsAndSetSharedMembers(
- rtc::scoped_refptr<PayloadRouter> send_payload_router,
- VCMProtectionCallback* vcm_protection_callback);
-
- // This function must be called before the corresponding ViEChannel is
- // deleted.
- void StopThreadsAndRemoveSharedMembers();
-
- void SetNetworkTransmissionState(bool is_transmitting);
-
- // Returns the id of the owning channel.
- int Owner() const;
-
- // Drops incoming packets before they get to the encoder.
- void Pause();
- void Restart();
-
- // Codec settings.
- uint8_t NumberOfCodecs();
- int32_t GetCodec(uint8_t list_index, VideoCodec* video_codec);
- int32_t RegisterExternalEncoder(VideoEncoder* encoder,
- uint8_t pl_type,
- bool internal_source);
- int32_t DeRegisterExternalEncoder(uint8_t pl_type);
- int32_t SetEncoder(const VideoCodec& video_codec);
- int32_t GetEncoder(VideoCodec* video_codec);
-
- // Scale or crop/pad image.
- int32_t ScaleInputImage(bool enable);
-
- // Implementing VideoCaptureCallback.
- void DeliverFrame(VideoFrame video_frame) override;
-
- int32_t SendKeyFrame();
-
- uint32_t LastObservedBitrateBps() const;
- int CodecTargetBitrate(uint32_t* bitrate) const;
- // Loss protection.
- int32_t UpdateProtectionMethod(bool nack, bool fec);
- bool nack_enabled() const { return nack_enabled_; }
-
- // Buffering mode.
- void SetSenderBufferingMode(int target_delay_ms);
-
- // Implements VideoEncoderRateObserver.
- void OnSetRates(uint32_t bitrate_bps, int framerate) override;
-
- // Implements VCMPacketizationCallback.
- int32_t SendData(uint8_t payload_type,
- const EncodedImage& encoded_image,
- const RTPFragmentationHeader& fragmentation_header,
- const RTPVideoHeader* rtp_video_hdr) override;
-
- // Implements VideoSendStatisticsCallback.
- int32_t SendStatistics(const uint32_t bit_rate,
- const uint32_t frame_rate) override;
-
- // Implements RtcpIntraFrameObserver.
- void OnReceivedIntraFrameRequest(uint32_t ssrc) override;
- void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) override;
- void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) override;
- void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) override;
-
- // Sets SSRCs for all streams.
- bool SetSsrcs(const std::vector<uint32_t>& ssrcs);
-
- void SetMinTransmitBitrate(int min_transmit_bitrate_kbps);
-
- // Lets the sender suspend video when the rate drops below
- // |threshold_bps|, and turns back on when the rate goes back up above
- // |threshold_bps| + |window_bps|.
- void SuspendBelowMinBitrate();
-
- // New-style callbacks, used by VideoSendStream.
- void RegisterPostEncodeImageCallback(
- EncodedImageCallback* post_encode_callback);
-
- int GetPaddingNeededBps() const;
-
- protected:
- // Called by BitrateObserver.
- void OnNetworkChanged(uint32_t bitrate_bps,
- uint8_t fraction_lost,
- int64_t round_trip_time_ms);
-
- private:
- bool EncoderPaused() const EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
- void TraceFrameDropStart() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
- void TraceFrameDropEnd() EXCLUSIVE_LOCKS_REQUIRED(data_cs_);
-
- const uint32_t number_of_cores_;
-
- const rtc::scoped_ptr<VideoProcessingModule> vpm_;
- const rtc::scoped_ptr<QMVideoSettingsCallback> qm_callback_;
- const rtc::scoped_ptr<VideoCodingModule> vcm_;
- rtc::scoped_refptr<PayloadRouter> send_payload_router_;
-
- rtc::scoped_ptr<CriticalSectionWrapper> data_cs_;
- rtc::scoped_ptr<BitrateObserver> bitrate_observer_;
-
- SendStatisticsProxy* const stats_proxy_;
- I420FrameCallback* const pre_encode_callback_;
- PacedSender* const pacer_;
- BitrateAllocator* const bitrate_allocator_;
-
- // The time we last received an input frame or encoded frame. This is used to
- // track when video is stopped long enough that we also want to stop sending
- // padding.
- int64_t time_of_last_frame_activity_ms_ GUARDED_BY(data_cs_);
- bool simulcast_enabled_ GUARDED_BY(data_cs_);
- int min_transmit_bitrate_kbps_ GUARDED_BY(data_cs_);
- uint32_t last_observed_bitrate_bps_ GUARDED_BY(data_cs_);
- int target_delay_ms_ GUARDED_BY(data_cs_);
- bool network_is_transmitting_ GUARDED_BY(data_cs_);
- bool encoder_paused_ GUARDED_BY(data_cs_);
- bool encoder_paused_and_dropped_frame_ GUARDED_BY(data_cs_);
- std::map<unsigned int, int64_t> time_last_intra_request_ms_
- GUARDED_BY(data_cs_);
-
- bool fec_enabled_;
- bool nack_enabled_;
-
- ProcessThread* module_process_thread_;
-
- bool has_received_sli_ GUARDED_BY(data_cs_);
- uint8_t picture_id_sli_ GUARDED_BY(data_cs_);
- bool has_received_rpsi_ GUARDED_BY(data_cs_);
- uint64_t picture_id_rpsi_ GUARDED_BY(data_cs_);
- std::map<uint32_t, int> ssrc_streams_ GUARDED_BY(data_cs_);
-
- bool video_suspended_ GUARDED_BY(data_cs_);
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_VIE_ENCODER_H_
diff --git a/webrtc/video_engine/vie_receiver.cc b/webrtc/video_engine/vie_receiver.cc
deleted file mode 100644
index 2e3b588302..0000000000
--- a/webrtc/video_engine/vie_receiver.cc
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * 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_receiver.h"
-
-#include <vector>
-
-#include "webrtc/base/logging.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
-#include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/metrics.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/system_wrappers/include/timestamp_extrapolator.h"
-#include "webrtc/system_wrappers/include/trace.h"
-
-namespace webrtc {
-
-static const int kPacketLogIntervalMs = 10000;
-
-ViEReceiver::ViEReceiver(VideoCodingModule* module_vcm,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtpFeedback* rtp_feedback)
- : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
- clock_(Clock::GetRealTimeClock()),
- rtp_header_parser_(RtpHeaderParser::Create()),
- rtp_payload_registry_(
- new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
- rtp_receiver_(
- RtpReceiver::CreateVideoReceiver(clock_,
- this,
- rtp_feedback,
- rtp_payload_registry_.get())),
- rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
- fec_receiver_(FecReceiver::Create(this)),
- rtp_rtcp_(NULL),
- vcm_(module_vcm),
- remote_bitrate_estimator_(remote_bitrate_estimator),
- ntp_estimator_(new RemoteNtpTimeEstimator(clock_)),
- receiving_(false),
- restored_packet_in_use_(false),
- receiving_ast_enabled_(false),
- receiving_cvo_enabled_(false),
- receiving_tsn_enabled_(false),
- last_packet_log_ms_(-1) {
- assert(remote_bitrate_estimator);
-}
-
-ViEReceiver::~ViEReceiver() {
- UpdateHistograms();
-}
-
-void ViEReceiver::UpdateHistograms() {
- FecPacketCounter counter = fec_receiver_->GetPacketCounter();
- if (counter.num_packets > 0) {
- RTC_HISTOGRAM_PERCENTAGE(
- "WebRTC.Video.ReceivedFecPacketsInPercent",
- static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets));
- }
- if (counter.num_fec_packets > 0) {
- RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec",
- static_cast<int>(counter.num_recovered_packets *
- 100 / counter.num_fec_packets));
- }
-}
-
-bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) {
- int8_t old_pltype = -1;
- if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName,
- kVideoPayloadTypeFrequency,
- 0,
- video_codec.maxBitrate,
- &old_pltype) != -1) {
- rtp_payload_registry_->DeRegisterReceivePayload(old_pltype);
- }
-
- return RegisterPayload(video_codec);
-}
-
-bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) {
- return rtp_receiver_->RegisterReceivePayload(video_codec.plName,
- video_codec.plType,
- kVideoPayloadTypeFrequency,
- 0,
- video_codec.maxBitrate) == 0;
-}
-
-void ViEReceiver::SetNackStatus(bool enable,
- int max_nack_reordering_threshold) {
- if (!enable) {
- // Reset the threshold back to the lower default threshold when NACK is
- // disabled since we no longer will be receiving retransmissions.
- max_nack_reordering_threshold = kDefaultMaxReorderingThreshold;
- }
- rtp_receive_statistics_->SetMaxReorderingThreshold(
- max_nack_reordering_threshold);
- rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff);
-}
-
-void ViEReceiver::SetRtxPayloadType(int payload_type,
- int associated_payload_type) {
- rtp_payload_registry_->SetRtxPayloadType(payload_type,
- associated_payload_type);
-}
-
-void ViEReceiver::SetUseRtxPayloadMappingOnRestore(bool val) {
- rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(val);
-}
-
-void ViEReceiver::SetRtxSsrc(uint32_t ssrc) {
- rtp_payload_registry_->SetRtxSsrc(ssrc);
-}
-
-bool ViEReceiver::GetRtxSsrc(uint32_t* ssrc) const {
- return rtp_payload_registry_->GetRtxSsrc(ssrc);
-}
-
-bool ViEReceiver::IsFecEnabled() const {
- return rtp_payload_registry_->ulpfec_payload_type() > -1;
-}
-
-uint32_t ViEReceiver::GetRemoteSsrc() const {
- return rtp_receiver_->SSRC();
-}
-
-int ViEReceiver::GetCsrcs(uint32_t* csrcs) const {
- return rtp_receiver_->CSRCs(csrcs);
-}
-
-void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) {
- rtp_rtcp_ = module;
-}
-
-RtpReceiver* ViEReceiver::GetRtpReceiver() const {
- return rtp_receiver_.get();
-}
-
-void ViEReceiver::RegisterRtpRtcpModules(
- const std::vector<RtpRtcp*>& rtp_modules) {
- CriticalSectionScoped cs(receive_cs_.get());
- // Only change the "simulcast" modules, the base module can be accessed
- // without a lock whereas the simulcast modules require locking as they can be
- // changed in runtime.
- rtp_rtcp_simulcast_ =
- std::vector<RtpRtcp*>(rtp_modules.begin() + 1, rtp_modules.end());
-}
-
-bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) {
- if (enable) {
- return rtp_header_parser_->RegisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset, id);
- } else {
- return rtp_header_parser_->DeregisterRtpHeaderExtension(
- kRtpExtensionTransmissionTimeOffset);
- }
-}
-
-bool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
- if (enable) {
- if (rtp_header_parser_->RegisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime, id)) {
- receiving_ast_enabled_ = true;
- return true;
- } else {
- return false;
- }
- } else {
- receiving_ast_enabled_ = false;
- return rtp_header_parser_->DeregisterRtpHeaderExtension(
- kRtpExtensionAbsoluteSendTime);
- }
-}
-
-bool ViEReceiver::SetReceiveVideoRotationStatus(bool enable, int id) {
- if (enable) {
- if (rtp_header_parser_->RegisterRtpHeaderExtension(
- kRtpExtensionVideoRotation, id)) {
- receiving_cvo_enabled_ = true;
- return true;
- } else {
- return false;
- }
- } else {
- receiving_cvo_enabled_ = false;
- return rtp_header_parser_->DeregisterRtpHeaderExtension(
- kRtpExtensionVideoRotation);
- }
-}
-
-bool ViEReceiver::SetReceiveTransportSequenceNumber(bool enable, int id) {
- if (enable) {
- if (rtp_header_parser_->RegisterRtpHeaderExtension(
- kRtpExtensionTransportSequenceNumber, id)) {
- receiving_tsn_enabled_ = true;
- return true;
- } else {
- return false;
- }
- } else {
- receiving_tsn_enabled_ = false;
- return rtp_header_parser_->DeregisterRtpHeaderExtension(
- kRtpExtensionTransportSequenceNumber);
- }
-}
-
-int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
- size_t rtp_packet_length,
- const PacketTime& packet_time) {
- return InsertRTPPacket(static_cast<const uint8_t*>(rtp_packet),
- rtp_packet_length, packet_time);
-}
-
-int ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet,
- size_t rtcp_packet_length) {
- return InsertRTCPPacket(static_cast<const uint8_t*>(rtcp_packet),
- rtcp_packet_length);
-}
-
-int32_t ViEReceiver::OnReceivedPayloadData(const uint8_t* payload_data,
- const size_t payload_size,
- const WebRtcRTPHeader* rtp_header) {
- WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
- rtp_header_with_ntp.ntp_time_ms =
- ntp_estimator_->Estimate(rtp_header->header.timestamp);
- if (vcm_->IncomingPacket(payload_data,
- payload_size,
- rtp_header_with_ntp) != 0) {
- // Check this...
- return -1;
- }
- return 0;
-}
-
-bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
- size_t rtp_packet_length) {
- RTPHeader header;
- if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
- return false;
- }
- header.payload_type_frequency = kVideoPayloadTypeFrequency;
- bool in_order = IsPacketInOrder(header);
- return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order);
-}
-
-int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet,
- size_t rtp_packet_length,
- const PacketTime& packet_time) {
- {
- CriticalSectionScoped cs(receive_cs_.get());
- if (!receiving_) {
- return -1;
- }
- }
-
- RTPHeader header;
- if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length,
- &header)) {
- return -1;
- }
- size_t payload_length = rtp_packet_length - header.headerLength;
- int64_t arrival_time_ms;
- int64_t now_ms = clock_->TimeInMilliseconds();
- if (packet_time.timestamp != -1)
- arrival_time_ms = (packet_time.timestamp + 500) / 1000;
- else
- arrival_time_ms = now_ms;
-
- {
- // Periodically log the RTP header of incoming packets.
- CriticalSectionScoped cs(receive_cs_.get());
- if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) {
- std::stringstream ss;
- ss << "Packet received on SSRC: " << header.ssrc << " with payload type: "
- << static_cast<int>(header.payloadType) << ", timestamp: "
- << header.timestamp << ", sequence number: " << header.sequenceNumber
- << ", arrival time: " << arrival_time_ms;
- if (header.extension.hasTransmissionTimeOffset)
- ss << ", toffset: " << header.extension.transmissionTimeOffset;
- if (header.extension.hasAbsoluteSendTime)
- ss << ", abs send time: " << header.extension.absoluteSendTime;
- LOG(LS_INFO) << ss.str();
- last_packet_log_ms_ = now_ms;
- }
- }
-
- remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_length,
- header, true);
- header.payload_type_frequency = kVideoPayloadTypeFrequency;
-
- bool in_order = IsPacketInOrder(header);
- rtp_payload_registry_->SetIncomingPayloadType(header);
- int ret = ReceivePacket(rtp_packet, rtp_packet_length, header, in_order)
- ? 0
- : -1;
- // Update receive statistics after ReceivePacket.
- // Receive statistics will be reset if the payload type changes (make sure
- // that the first packet is included in the stats).
- rtp_receive_statistics_->IncomingPacket(
- header, rtp_packet_length, IsPacketRetransmitted(header, in_order));
- return ret;
-}
-
-bool ViEReceiver::ReceivePacket(const uint8_t* packet,
- size_t packet_length,
- const RTPHeader& header,
- bool in_order) {
- if (rtp_payload_registry_->IsEncapsulated(header)) {
- return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
- }
- const uint8_t* payload = packet + header.headerLength;
- assert(packet_length >= header.headerLength);
- size_t payload_length = packet_length - header.headerLength;
- PayloadUnion payload_specific;
- if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
- &payload_specific)) {
- return false;
- }
- return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
- payload_specific, in_order);
-}
-
-bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet,
- size_t packet_length,
- const RTPHeader& header) {
- if (rtp_payload_registry_->IsRed(header)) {
- int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type();
- if (packet[header.headerLength] == ulpfec_pt) {
- rtp_receive_statistics_->FecPacketReceived(header, packet_length);
- // Notify vcm about received FEC packets to avoid NACKing these packets.
- NotifyReceiverOfFecPacket(header);
- }
- if (fec_receiver_->AddReceivedRedPacket(
- header, packet, packet_length, ulpfec_pt) != 0) {
- return false;
- }
- return fec_receiver_->ProcessReceivedFec() == 0;
- } else if (rtp_payload_registry_->IsRtx(header)) {
- if (header.headerLength + header.paddingLength == packet_length) {
- // This is an empty packet and should be silently dropped before trying to
- // parse the RTX header.
- return true;
- }
- // Remove the RTX header and parse the original RTP header.
- if (packet_length < header.headerLength)
- return false;
- if (packet_length > sizeof(restored_packet_))
- return false;
- CriticalSectionScoped cs(receive_cs_.get());
- if (restored_packet_in_use_) {
- LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet.";
- return false;
- }
- if (!rtp_payload_registry_->RestoreOriginalPacket(
- restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(),
- header)) {
- LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header";
- return false;
- }
- restored_packet_in_use_ = true;
- bool ret = OnRecoveredPacket(restored_packet_, packet_length);
- restored_packet_in_use_ = false;
- return ret;
- }
- return false;
-}
-
-void ViEReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) {
- int8_t last_media_payload_type =
- rtp_payload_registry_->last_received_media_payload_type();
- if (last_media_payload_type < 0) {
- LOG(LS_WARNING) << "Failed to get last media payload type.";
- return;
- }
- // Fake an empty media packet.
- WebRtcRTPHeader rtp_header = {};
- rtp_header.header = header;
- rtp_header.header.payloadType = last_media_payload_type;
- rtp_header.header.paddingLength = 0;
- PayloadUnion payload_specific;
- if (!rtp_payload_registry_->GetPayloadSpecifics(last_media_payload_type,
- &payload_specific)) {
- LOG(LS_WARNING) << "Failed to get payload specifics.";
- return;
- }
- rtp_header.type.Video.codec = payload_specific.Video.videoCodecType;
- rtp_header.type.Video.rotation = kVideoRotation_0;
- if (header.extension.hasVideoRotation) {
- rtp_header.type.Video.rotation =
- ConvertCVOByteToVideoRotation(header.extension.videoRotation);
- }
- OnReceivedPayloadData(NULL, 0, &rtp_header);
-}
-
-int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet,
- size_t rtcp_packet_length) {
- {
- CriticalSectionScoped cs(receive_cs_.get());
- if (!receiving_) {
- return -1;
- }
-
- for (RtpRtcp* rtp_rtcp : rtp_rtcp_simulcast_)
- rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
- }
- assert(rtp_rtcp_); // Should be set by owner at construction time.
- int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
- if (ret != 0) {
- return ret;
- }
-
- int64_t rtt = 0;
- rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, NULL, NULL, NULL);
- if (rtt == 0) {
- // Waiting for valid rtt.
- return 0;
- }
- uint32_t ntp_secs = 0;
- uint32_t ntp_frac = 0;
- uint32_t rtp_timestamp = 0;
- if (0 != rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL,
- &rtp_timestamp)) {
- // Waiting for RTCP.
- return 0;
- }
- ntp_estimator_->UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp);
-
- return 0;
-}
-
-void ViEReceiver::StartReceive() {
- CriticalSectionScoped cs(receive_cs_.get());
- receiving_ = true;
-}
-
-void ViEReceiver::StopReceive() {
- CriticalSectionScoped cs(receive_cs_.get());
- receiving_ = false;
-}
-
-ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const {
- return rtp_receive_statistics_.get();
-}
-
-bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const {
- StreamStatistician* statistician =
- rtp_receive_statistics_->GetStatistician(header.ssrc);
- if (!statistician)
- return false;
- return statistician->IsPacketInOrder(header.sequenceNumber);
-}
-
-bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header,
- bool in_order) const {
- // Retransmissions are handled separately if RTX is enabled.
- if (rtp_payload_registry_->RtxEnabled())
- return false;
- StreamStatistician* statistician =
- rtp_receive_statistics_->GetStatistician(header.ssrc);
- if (!statistician)
- return false;
- // Check if this is a retransmission.
- int64_t min_rtt = 0;
- rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
- return !in_order &&
- statistician->IsRetransmitOfOldPacket(header, min_rtt);
-}
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_receiver.h b/webrtc/video_engine/vie_receiver.h
deleted file mode 100644
index cd069eaa5b..0000000000
--- a/webrtc/video_engine/vie_receiver.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_VIE_RECEIVER_H_
-#define WEBRTC_VIDEO_ENGINE_VIE_RECEIVER_H_
-
-#include <list>
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/engine_configurations.h"
-#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/typedefs.h"
-#include "webrtc/video_engine/vie_defines.h"
-
-namespace webrtc {
-
-class CriticalSectionWrapper;
-class FecReceiver;
-class RemoteNtpTimeEstimator;
-class ReceiveStatistics;
-class RemoteBitrateEstimator;
-class RtpHeaderParser;
-class RTPPayloadRegistry;
-class RtpReceiver;
-class RtpRtcp;
-class VideoCodingModule;
-struct ReceiveBandwidthEstimatorStats;
-
-class ViEReceiver : public RtpData {
- public:
- ViEReceiver(VideoCodingModule* module_vcm,
- RemoteBitrateEstimator* remote_bitrate_estimator,
- RtpFeedback* rtp_feedback);
- ~ViEReceiver();
-
- bool SetReceiveCodec(const VideoCodec& video_codec);
- bool RegisterPayload(const VideoCodec& video_codec);
-
- void SetNackStatus(bool enable, int max_nack_reordering_threshold);
- void SetRtxPayloadType(int payload_type, int associated_payload_type);
- // If set to true, the RTX payload type mapping supplied in
- // |SetRtxPayloadType| will be used when restoring RTX packets. Without it,
- // RTX packets will always be restored to the last non-RTX packet payload type
- // received.
- void SetUseRtxPayloadMappingOnRestore(bool val);
- void SetRtxSsrc(uint32_t ssrc);
- bool GetRtxSsrc(uint32_t* ssrc) const;
-
- bool IsFecEnabled() const;
-
- uint32_t GetRemoteSsrc() const;
- int GetCsrcs(uint32_t* csrcs) const;
-
- void SetRtpRtcpModule(RtpRtcp* module);
-
- RtpReceiver* GetRtpReceiver() const;
-
- void RegisterRtpRtcpModules(const std::vector<RtpRtcp*>& rtp_modules);
-
- bool SetReceiveTimestampOffsetStatus(bool enable, int id);
- bool SetReceiveAbsoluteSendTimeStatus(bool enable, int id);
- bool SetReceiveVideoRotationStatus(bool enable, int id);
- bool SetReceiveTransportSequenceNumber(bool enable, int id);
-
- void StartReceive();
- void StopReceive();
-
- // Receives packets from external transport.
- int ReceivedRTPPacket(const void* rtp_packet, size_t rtp_packet_length,
- const PacketTime& packet_time);
- int ReceivedRTCPPacket(const void* rtcp_packet, size_t rtcp_packet_length);
-
- // Implements RtpData.
- int32_t OnReceivedPayloadData(const uint8_t* payload_data,
- const size_t payload_size,
- const WebRtcRTPHeader* rtp_header) override;
- bool OnRecoveredPacket(const uint8_t* packet, size_t packet_length) override;
-
- ReceiveStatistics* GetReceiveStatistics() const;
- private:
- int InsertRTPPacket(const uint8_t* rtp_packet, size_t rtp_packet_length,
- const PacketTime& packet_time);
- bool ReceivePacket(const uint8_t* packet,
- size_t packet_length,
- const RTPHeader& header,
- bool in_order);
- // Parses and handles for instance RTX and RED headers.
- // This function assumes that it's being called from only one thread.
- bool ParseAndHandleEncapsulatingHeader(const uint8_t* packet,
- size_t packet_length,
- const RTPHeader& header);
- void NotifyReceiverOfFecPacket(const RTPHeader& header);
- int InsertRTCPPacket(const uint8_t* rtcp_packet, size_t rtcp_packet_length);
- bool IsPacketInOrder(const RTPHeader& header) const;
- bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const;
- void UpdateHistograms();
-
- rtc::scoped_ptr<CriticalSectionWrapper> receive_cs_;
- Clock* clock_;
- rtc::scoped_ptr<RtpHeaderParser> rtp_header_parser_;
- rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
- rtc::scoped_ptr<RtpReceiver> rtp_receiver_;
- const rtc::scoped_ptr<ReceiveStatistics> rtp_receive_statistics_;
- rtc::scoped_ptr<FecReceiver> fec_receiver_;
- RtpRtcp* rtp_rtcp_;
- std::vector<RtpRtcp*> rtp_rtcp_simulcast_;
- VideoCodingModule* vcm_;
- RemoteBitrateEstimator* remote_bitrate_estimator_;
-
- rtc::scoped_ptr<RemoteNtpTimeEstimator> ntp_estimator_;
-
- bool receiving_;
- uint8_t restored_packet_[kViEMaxMtu];
- bool restored_packet_in_use_;
- bool receiving_ast_enabled_;
- bool receiving_cvo_enabled_;
- bool receiving_tsn_enabled_;
- int64_t last_packet_log_ms_;
-};
-
-} // namespace webrt
-
-#endif // WEBRTC_VIDEO_ENGINE_VIE_RECEIVER_H_
diff --git a/webrtc/video_engine/vie_remb.cc b/webrtc/video_engine/vie_remb.cc
deleted file mode 100644
index b347f2ee00..0000000000
--- a/webrtc/video_engine/vie_remb.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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_remb.h"
-
-#include <assert.h>
-
-#include <algorithm>
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/utility/interface/process_thread.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/system_wrappers/include/trace.h"
-
-namespace webrtc {
-
-const int kRembSendIntervalMs = 200;
-
-// % threshold for if we should send a new REMB asap.
-const unsigned int kSendThresholdPercent = 97;
-
-VieRemb::VieRemb()
- : list_crit_(CriticalSectionWrapper::CreateCriticalSection()),
- last_remb_time_(TickTime::MillisecondTimestamp()),
- last_send_bitrate_(0),
- bitrate_(0) {}
-
-VieRemb::~VieRemb() {}
-
-void VieRemb::AddReceiveChannel(RtpRtcp* rtp_rtcp) {
- assert(rtp_rtcp);
-
- CriticalSectionScoped cs(list_crit_.get());
- if (std::find(receive_modules_.begin(), receive_modules_.end(), rtp_rtcp) !=
- receive_modules_.end())
- return;
-
- // The module probably doesn't have a remote SSRC yet, so don't add it to the
- // map.
- receive_modules_.push_back(rtp_rtcp);
-}
-
-void VieRemb::RemoveReceiveChannel(RtpRtcp* rtp_rtcp) {
- assert(rtp_rtcp);
-
- CriticalSectionScoped cs(list_crit_.get());
- for (RtpModules::iterator it = receive_modules_.begin();
- it != receive_modules_.end(); ++it) {
- if ((*it) == rtp_rtcp) {
- receive_modules_.erase(it);
- break;
- }
- }
-}
-
-void VieRemb::AddRembSender(RtpRtcp* rtp_rtcp) {
- assert(rtp_rtcp);
-
- CriticalSectionScoped cs(list_crit_.get());
-
- // Verify this module hasn't been added earlier.
- if (std::find(rtcp_sender_.begin(), rtcp_sender_.end(), rtp_rtcp) !=
- rtcp_sender_.end())
- return;
- rtcp_sender_.push_back(rtp_rtcp);
-}
-
-void VieRemb::RemoveRembSender(RtpRtcp* rtp_rtcp) {
- assert(rtp_rtcp);
-
- CriticalSectionScoped cs(list_crit_.get());
- for (RtpModules::iterator it = rtcp_sender_.begin();
- it != rtcp_sender_.end(); ++it) {
- if ((*it) == rtp_rtcp) {
- rtcp_sender_.erase(it);
- return;
- }
- }
-}
-
-bool VieRemb::InUse() const {
- CriticalSectionScoped cs(list_crit_.get());
- if (receive_modules_.empty() && rtcp_sender_.empty())
- return false;
- else
- return true;
-}
-
-void VieRemb::OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
- unsigned int bitrate) {
- list_crit_->Enter();
- // If we already have an estimate, check if the new total estimate is below
- // kSendThresholdPercent of the previous estimate.
- if (last_send_bitrate_ > 0) {
- unsigned int new_remb_bitrate = last_send_bitrate_ - bitrate_ + bitrate;
-
- if (new_remb_bitrate < kSendThresholdPercent * last_send_bitrate_ / 100) {
- // The new bitrate estimate is less than kSendThresholdPercent % of the
- // last report. Send a REMB asap.
- last_remb_time_ = TickTime::MillisecondTimestamp() - kRembSendIntervalMs;
- }
- }
- bitrate_ = bitrate;
-
- // Calculate total receive bitrate estimate.
- int64_t now = TickTime::MillisecondTimestamp();
-
- if (now - last_remb_time_ < kRembSendIntervalMs) {
- list_crit_->Leave();
- return;
- }
- last_remb_time_ = now;
-
- if (ssrcs.empty() || receive_modules_.empty()) {
- list_crit_->Leave();
- return;
- }
-
- // Send a REMB packet.
- RtpRtcp* sender = NULL;
- if (!rtcp_sender_.empty()) {
- sender = rtcp_sender_.front();
- } else {
- sender = receive_modules_.front();
- }
- last_send_bitrate_ = bitrate_;
-
- list_crit_->Leave();
-
- if (sender) {
- sender->SetREMBData(bitrate_, ssrcs);
- }
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_remb.h b/webrtc/video_engine/vie_remb.h
deleted file mode 100644
index 9f38259ca8..0000000000
--- a/webrtc/video_engine/vie_remb.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef WEBRTC_VIDEO_ENGINE_VIE_REMB_H_
-#define WEBRTC_VIDEO_ENGINE_VIE_REMB_H_
-
-#include <list>
-#include <utility>
-#include <vector>
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/interface/module.h"
-#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-
-namespace webrtc {
-
-class CriticalSectionWrapper;
-class ProcessThread;
-class RtpRtcp;
-
-class VieRemb : public RemoteBitrateObserver {
- public:
- VieRemb();
- ~VieRemb();
-
- // Called to add a receive channel to include in the REMB packet.
- void AddReceiveChannel(RtpRtcp* rtp_rtcp);
-
- // Removes the specified channel from REMB estimate.
- void RemoveReceiveChannel(RtpRtcp* rtp_rtcp);
-
- // Called to add a module that can generate and send REMB RTCP.
- void AddRembSender(RtpRtcp* rtp_rtcp);
-
- // Removes a REMB RTCP sender.
- void RemoveRembSender(RtpRtcp* rtp_rtcp);
-
- // Returns true if the instance is in use, false otherwise.
- bool InUse() const;
-
- // Called every time there is a new bitrate estimate for a receive channel
- // group. This call will trigger a new RTCP REMB packet if the bitrate
- // estimate has decreased or if no RTCP REMB packet has been sent for
- // a certain time interval.
- // Implements RtpReceiveBitrateUpdate.
- virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
- unsigned int bitrate);
-
- private:
- typedef std::list<RtpRtcp*> RtpModules;
-
- rtc::scoped_ptr<CriticalSectionWrapper> list_crit_;
-
- // The last time a REMB was sent.
- int64_t last_remb_time_;
- unsigned int last_send_bitrate_;
-
- // All RtpRtcp modules to include in the REMB packet.
- RtpModules receive_modules_;
-
- // All modules that can send REMB RTCP.
- RtpModules rtcp_sender_;
-
- // The last bitrate update.
- unsigned int bitrate_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_VIE_REMB_H_
diff --git a/webrtc/video_engine/vie_remb_unittest.cc b/webrtc/video_engine/vie_remb_unittest.cc
deleted file mode 100644
index 3289c4b822..0000000000
--- a/webrtc/video_engine/vie_remb_unittest.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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.
- */
-
-
-// This file includes unit tests for ViERemb.
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include <vector>
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
-#include "webrtc/modules/utility/interface/mock/mock_process_thread.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/video_engine/vie_remb.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::NiceMock;
-using ::testing::Return;
-
-namespace webrtc {
-
-class ViERembTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- TickTime::UseFakeClock(12345);
- process_thread_.reset(new NiceMock<MockProcessThread>);
- vie_remb_.reset(new VieRemb());
- }
- rtc::scoped_ptr<MockProcessThread> process_thread_;
- rtc::scoped_ptr<VieRemb> vie_remb_;
-};
-
-TEST_F(ViERembTest, OneModuleTestForSendingRemb) {
- MockRtpRtcp rtp;
- vie_remb_->AddReceiveChannel(&rtp);
- vie_remb_->AddRembSender(&rtp);
-
- const unsigned int bitrate_estimate = 456;
- unsigned int ssrc = 1234;
- std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Lower bitrate to send another REMB packet.
- EXPECT_CALL(rtp, SetREMBData(bitrate_estimate - 100, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate - 100);
-
- vie_remb_->RemoveReceiveChannel(&rtp);
- vie_remb_->RemoveRembSender(&rtp);
-}
-
-TEST_F(ViERembTest, LowerEstimateToSendRemb) {
- MockRtpRtcp rtp;
- vie_remb_->AddReceiveChannel(&rtp);
- vie_remb_->AddRembSender(&rtp);
-
- unsigned int bitrate_estimate = 456;
- unsigned int ssrc = 1234;
- std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
- // Call OnReceiveBitrateChanged twice to get a first estimate.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Lower the estimate with more than 3% to trigger a call to SetREMBData right
- // away.
- bitrate_estimate = bitrate_estimate - 100;
- EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-}
-
-TEST_F(ViERembTest, VerifyIncreasingAndDecreasing) {
- MockRtpRtcp rtp_0;
- MockRtpRtcp rtp_1;
- vie_remb_->AddReceiveChannel(&rtp_0);
- vie_remb_->AddRembSender(&rtp_0);
- vie_remb_->AddReceiveChannel(&rtp_1);
-
- unsigned int bitrate_estimate[] = { 456, 789 };
- unsigned int ssrc[] = { 1234, 5678 };
- std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[0]);
-
- // Call OnReceiveBitrateChanged twice to get a first estimate.
- EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate[0], ssrcs))
- .Times(1);
- TickTime::AdvanceFakeClock(1000);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[0]);
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[1] + 100);
-
- // Lower the estimate to trigger a callback.
- EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate[1], ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate[1]);
-
- vie_remb_->RemoveReceiveChannel(&rtp_0);
- vie_remb_->RemoveRembSender(&rtp_0);
- vie_remb_->RemoveReceiveChannel(&rtp_1);
-}
-
-TEST_F(ViERembTest, NoRembForIncreasedBitrate) {
- MockRtpRtcp rtp_0;
- MockRtpRtcp rtp_1;
- vie_remb_->AddReceiveChannel(&rtp_0);
- vie_remb_->AddRembSender(&rtp_0);
- vie_remb_->AddReceiveChannel(&rtp_1);
-
- unsigned int bitrate_estimate = 456;
- unsigned int ssrc[] = { 1234, 5678 };
- std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
- // Call OnReceiveBitrateChanged twice to get a first estimate.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Increased estimate shouldn't trigger a callback right away.
- EXPECT_CALL(rtp_0, SetREMBData(_, _))
- .Times(0);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate + 1);
-
- // Decreasing the estimate less than 3% shouldn't trigger a new callback.
- EXPECT_CALL(rtp_0, SetREMBData(_, _))
- .Times(0);
- int lower_estimate = bitrate_estimate * 98 / 100;
- vie_remb_->OnReceiveBitrateChanged(ssrcs, lower_estimate);
-
- vie_remb_->RemoveReceiveChannel(&rtp_1);
- vie_remb_->RemoveReceiveChannel(&rtp_0);
- vie_remb_->RemoveRembSender(&rtp_0);
-}
-
-TEST_F(ViERembTest, ChangeSendRtpModule) {
- MockRtpRtcp rtp_0;
- MockRtpRtcp rtp_1;
- vie_remb_->AddReceiveChannel(&rtp_0);
- vie_remb_->AddRembSender(&rtp_0);
- vie_remb_->AddReceiveChannel(&rtp_1);
-
- unsigned int bitrate_estimate = 456;
- unsigned int ssrc[] = { 1234, 5678 };
- std::vector<unsigned int> ssrcs(ssrc, ssrc + sizeof(ssrc) / sizeof(ssrc[0]));
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
- // Call OnReceiveBitrateChanged twice to get a first estimate.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Decrease estimate to trigger a REMB.
- bitrate_estimate = bitrate_estimate - 100;
- EXPECT_CALL(rtp_0, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Remove the sending module, add it again -> should get remb on the second
- // module.
- vie_remb_->RemoveRembSender(&rtp_0);
- vie_remb_->AddRembSender(&rtp_1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- bitrate_estimate = bitrate_estimate - 100;
- EXPECT_CALL(rtp_1, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- vie_remb_->RemoveReceiveChannel(&rtp_0);
- vie_remb_->RemoveReceiveChannel(&rtp_1);
-}
-
-TEST_F(ViERembTest, OnlyOneRembForDoubleProcess) {
- MockRtpRtcp rtp;
- unsigned int bitrate_estimate = 456;
- unsigned int ssrc = 1234;
- std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
-
- vie_remb_->AddReceiveChannel(&rtp);
- vie_remb_->AddRembSender(&rtp);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
- // Call OnReceiveBitrateChanged twice to get a first estimate.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(rtp, SetREMBData(_, _))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Lower the estimate, should trigger a call to SetREMBData right away.
- bitrate_estimate = bitrate_estimate - 100;
- EXPECT_CALL(rtp, SetREMBData(bitrate_estimate, ssrcs))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Call OnReceiveBitrateChanged again, this should not trigger a new callback.
- EXPECT_CALL(rtp, SetREMBData(_, _))
- .Times(0);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
- vie_remb_->RemoveReceiveChannel(&rtp);
- vie_remb_->RemoveRembSender(&rtp);
-}
-
-// Only register receiving modules and make sure we fallback to trigger a REMB
-// packet on this one.
-TEST_F(ViERembTest, NoSendingRtpModule) {
- MockRtpRtcp rtp;
- vie_remb_->AddReceiveChannel(&rtp);
-
- unsigned int bitrate_estimate = 456;
- unsigned int ssrc = 1234;
- std::vector<unsigned int> ssrcs(&ssrc, &ssrc + 1);
-
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Call OnReceiveBitrateChanged twice to get a first estimate.
- TickTime::AdvanceFakeClock(1000);
- EXPECT_CALL(rtp, SetREMBData(_, _))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-
- // Lower the estimate to trigger a new packet REMB packet.
- bitrate_estimate = bitrate_estimate - 100;
- EXPECT_CALL(rtp, SetREMBData(_, _))
- .Times(1);
- vie_remb_->OnReceiveBitrateChanged(ssrcs, bitrate_estimate);
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_sync_module.cc b/webrtc/video_engine/vie_sync_module.cc
deleted file mode 100644
index 1c5d877cd2..0000000000
--- a/webrtc/video_engine/vie_sync_module.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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_sync_module.h"
-
-#include "webrtc/base/logging.h"
-#include "webrtc/base/trace_event.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/video_coding/main/interface/video_coding.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/video_engine/stream_synchronization.h"
-#include "webrtc/voice_engine/include/voe_video_sync.h"
-
-namespace webrtc {
-
-int UpdateMeasurements(StreamSynchronization::Measurements* stream,
- const RtpRtcp& rtp_rtcp, const RtpReceiver& receiver) {
- if (!receiver.Timestamp(&stream->latest_timestamp))
- return -1;
- if (!receiver.LastReceivedTimeMs(&stream->latest_receive_time_ms))
- return -1;
-
- uint32_t ntp_secs = 0;
- uint32_t ntp_frac = 0;
- uint32_t rtp_timestamp = 0;
- if (0 != rtp_rtcp.RemoteNTP(&ntp_secs,
- &ntp_frac,
- NULL,
- NULL,
- &rtp_timestamp)) {
- return -1;
- }
-
- bool new_rtcp_sr = false;
- if (!UpdateRtcpList(
- ntp_secs, ntp_frac, rtp_timestamp, &stream->rtcp, &new_rtcp_sr)) {
- return -1;
- }
-
- return 0;
-}
-
-ViESyncModule::ViESyncModule(VideoCodingModule* vcm)
- : data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
- vcm_(vcm),
- video_receiver_(NULL),
- video_rtp_rtcp_(NULL),
- voe_channel_id_(-1),
- voe_sync_interface_(NULL),
- last_sync_time_(TickTime::Now()),
- sync_() {
-}
-
-ViESyncModule::~ViESyncModule() {
-}
-
-int ViESyncModule::ConfigureSync(int voe_channel_id,
- VoEVideoSync* voe_sync_interface,
- RtpRtcp* video_rtcp_module,
- RtpReceiver* video_receiver) {
- CriticalSectionScoped cs(data_cs_.get());
- // Prevent expensive no-ops.
- if (voe_channel_id_ == voe_channel_id &&
- voe_sync_interface_ == voe_sync_interface &&
- video_receiver_ == video_receiver &&
- video_rtp_rtcp_ == video_rtcp_module) {
- return 0;
- }
- voe_channel_id_ = voe_channel_id;
- voe_sync_interface_ = voe_sync_interface;
- video_receiver_ = video_receiver;
- video_rtp_rtcp_ = video_rtcp_module;
- sync_.reset(
- new StreamSynchronization(video_rtp_rtcp_->SSRC(), voe_channel_id));
-
- if (!voe_sync_interface) {
- voe_channel_id_ = -1;
- if (voe_channel_id >= 0) {
- // Trying to set a voice channel but no interface exist.
- return -1;
- }
- return 0;
- }
- return 0;
-}
-
-int ViESyncModule::VoiceChannel() {
- return voe_channel_id_;
-}
-
-int64_t ViESyncModule::TimeUntilNextProcess() {
- const int64_t kSyncIntervalMs = 1000;
- return kSyncIntervalMs - (TickTime::Now() - last_sync_time_).Milliseconds();
-}
-
-int32_t ViESyncModule::Process() {
- CriticalSectionScoped cs(data_cs_.get());
- last_sync_time_ = TickTime::Now();
-
- const int current_video_delay_ms = vcm_->Delay();
-
- if (voe_channel_id_ == -1) {
- return 0;
- }
- assert(video_rtp_rtcp_ && voe_sync_interface_);
- assert(sync_.get());
-
- int audio_jitter_buffer_delay_ms = 0;
- int playout_buffer_delay_ms = 0;
- if (voe_sync_interface_->GetDelayEstimate(voe_channel_id_,
- &audio_jitter_buffer_delay_ms,
- &playout_buffer_delay_ms) != 0) {
- return 0;
- }
- const int current_audio_delay_ms = audio_jitter_buffer_delay_ms +
- playout_buffer_delay_ms;
-
- RtpRtcp* voice_rtp_rtcp = NULL;
- RtpReceiver* voice_receiver = NULL;
- if (0 != voe_sync_interface_->GetRtpRtcp(voe_channel_id_, &voice_rtp_rtcp,
- &voice_receiver)) {
- return 0;
- }
- assert(voice_rtp_rtcp);
- assert(voice_receiver);
-
- if (UpdateMeasurements(&video_measurement_, *video_rtp_rtcp_,
- *video_receiver_) != 0) {
- return 0;
- }
-
- if (UpdateMeasurements(&audio_measurement_, *voice_rtp_rtcp,
- *voice_receiver) != 0) {
- return 0;
- }
-
- int relative_delay_ms;
- // Calculate how much later or earlier the audio stream is compared to video.
- if (!sync_->ComputeRelativeDelay(audio_measurement_, video_measurement_,
- &relative_delay_ms)) {
- return 0;
- }
-
- TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay", current_video_delay_ms);
- TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay", current_audio_delay_ms);
- TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms);
- int target_audio_delay_ms = 0;
- int target_video_delay_ms = current_video_delay_ms;
- // Calculate the necessary extra audio delay and desired total video
- // delay to get the streams in sync.
- if (!sync_->ComputeDelays(relative_delay_ms,
- current_audio_delay_ms,
- &target_audio_delay_ms,
- &target_video_delay_ms)) {
- return 0;
- }
-
- if (voe_sync_interface_->SetMinimumPlayoutDelay(
- voe_channel_id_, target_audio_delay_ms) == -1) {
- LOG(LS_ERROR) << "Error setting voice delay.";
- }
- vcm_->SetMinimumPlayoutDelay(target_video_delay_ms);
- return 0;
-}
-
-int ViESyncModule::SetTargetBufferingDelay(int target_delay_ms) {
- CriticalSectionScoped cs(data_cs_.get());
- if (!voe_sync_interface_) {
- LOG(LS_ERROR) << "voe_sync_interface_ NULL, can't set playout delay.";
- return -1;
- }
- sync_->SetTargetBufferingDelay(target_delay_ms);
- // Setting initial playout delay to voice engine (video engine is updated via
- // the VCM interface).
- voe_sync_interface_->SetInitialPlayoutDelay(voe_channel_id_,
- target_delay_ms);
- return 0;
-}
-
-} // namespace webrtc
diff --git a/webrtc/video_engine/vie_sync_module.h b/webrtc/video_engine/vie_sync_module.h
deleted file mode 100644
index ea2ae0bd51..0000000000
--- a/webrtc/video_engine/vie_sync_module.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.
- */
-
-// ViESyncModule is responsible for synchronization audio and video for a given
-// VoE and ViE channel couple.
-
-#ifndef WEBRTC_VIDEO_ENGINE_VIE_SYNC_MODULE_H_
-#define WEBRTC_VIDEO_ENGINE_VIE_SYNC_MODULE_H_
-
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/modules/interface/module.h"
-#include "webrtc/system_wrappers/include/tick_util.h"
-#include "webrtc/video_engine/stream_synchronization.h"
-#include "webrtc/voice_engine/include/voe_video_sync.h"
-
-namespace webrtc {
-
-class CriticalSectionWrapper;
-class RtpRtcp;
-class VideoCodingModule;
-class ViEChannel;
-class VoEVideoSync;
-
-class ViESyncModule : public Module {
- public:
- explicit ViESyncModule(VideoCodingModule* vcm);
- ~ViESyncModule();
-
- int ConfigureSync(int voe_channel_id,
- VoEVideoSync* voe_sync_interface,
- RtpRtcp* video_rtcp_module,
- RtpReceiver* video_receiver);
-
- int VoiceChannel();
-
- // Set target delay for buffering mode (0 = real-time mode).
- int SetTargetBufferingDelay(int target_delay_ms);
-
- // Implements Module.
- int64_t TimeUntilNextProcess() override;
- int32_t Process() override;
-
- private:
- rtc::scoped_ptr<CriticalSectionWrapper> data_cs_;
- VideoCodingModule* const vcm_;
- RtpReceiver* video_receiver_;
- RtpRtcp* video_rtp_rtcp_;
- int voe_channel_id_;
- VoEVideoSync* voe_sync_interface_;
- TickTime last_sync_time_;
- rtc::scoped_ptr<StreamSynchronization> sync_;
- StreamSynchronization::Measurements audio_measurement_;
- StreamSynchronization::Measurements video_measurement_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_VIDEO_ENGINE_VIE_SYNC_MODULE_H_