Implementing a packet router class, used to route RTP packets to the
sending RTP module for the specified simulcast layer a frame belongs to. This CL also removes the corresponding functionality from the RTP RTCP module and fixes lint warnings in the files touched. BUG=769 TEST=New unittest and manual tests R=stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/39629004 Cr-Commit-Position: refs/heads/master@{#8267} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8267 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
10a9e924eb
commit
02270cd718
@ -13,6 +13,8 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/system_wrappers/interface/logging.h"
|
||||
#include "webrtc/system_wrappers/interface/trace.h"
|
||||
@ -491,74 +493,21 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData(
|
||||
size_t payload_size,
|
||||
const RTPFragmentationHeader* fragmentation,
|
||||
const RTPVideoHeader* rtp_video_hdr) {
|
||||
rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms);
|
||||
assert(!IsDefaultModule());
|
||||
|
||||
if (!IsDefaultModule()) {
|
||||
// Don't send RTCP from default module.
|
||||
if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
|
||||
rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms);
|
||||
if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
|
||||
rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
|
||||
}
|
||||
return rtp_sender_.SendOutgoingData(frame_type,
|
||||
payload_type,
|
||||
time_stamp,
|
||||
capture_time_ms,
|
||||
payload_data,
|
||||
payload_size,
|
||||
fragmentation,
|
||||
NULL,
|
||||
&(rtp_video_hdr->codecHeader));
|
||||
}
|
||||
int32_t ret_val = -1;
|
||||
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
|
||||
if (simulcast_) {
|
||||
if (rtp_video_hdr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
int idx = 0;
|
||||
std::vector<ModuleRtpRtcpImpl*>::iterator it = child_modules_.begin();
|
||||
for (; idx < rtp_video_hdr->simulcastIdx; ++it) {
|
||||
if (it == child_modules_.end()) {
|
||||
return -1;
|
||||
}
|
||||
if ((*it)->SendingMedia()) {
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
for (; it != child_modules_.end(); ++it) {
|
||||
if ((*it)->SendingMedia()) {
|
||||
break;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
if (it == child_modules_.end()) {
|
||||
return -1;
|
||||
}
|
||||
return (*it)->SendOutgoingData(frame_type,
|
||||
payload_type,
|
||||
time_stamp,
|
||||
capture_time_ms,
|
||||
payload_data,
|
||||
payload_size,
|
||||
fragmentation,
|
||||
rtp_video_hdr);
|
||||
} else {
|
||||
std::vector<ModuleRtpRtcpImpl*>::iterator it = child_modules_.begin();
|
||||
// Send to all "child" modules
|
||||
while (it != child_modules_.end()) {
|
||||
if ((*it)->SendingMedia()) {
|
||||
ret_val = (*it)->SendOutgoingData(frame_type,
|
||||
payload_type,
|
||||
time_stamp,
|
||||
capture_time_ms,
|
||||
payload_data,
|
||||
payload_size,
|
||||
fragmentation,
|
||||
rtp_video_hdr);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
}
|
||||
return ret_val;
|
||||
return rtp_sender_.SendOutgoingData(frame_type,
|
||||
payload_type,
|
||||
time_stamp,
|
||||
capture_time_ms,
|
||||
payload_data,
|
||||
payload_size,
|
||||
fragmentation,
|
||||
NULL,
|
||||
&(rtp_video_hdr->codecHeader));
|
||||
}
|
||||
|
||||
bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc,
|
||||
@ -1346,4 +1295,4 @@ bool ModuleRtpRtcpImpl::IsDefaultModule() const {
|
||||
return !child_modules_.empty();
|
||||
}
|
||||
|
||||
} // Namespace webrtc
|
||||
} // namespace webrtc
|
||||
|
@ -29,6 +29,8 @@ source_set("video_engine_core") {
|
||||
"encoder_state_feedback.h",
|
||||
"overuse_frame_detector.cc",
|
||||
"overuse_frame_detector.h",
|
||||
"payload_router.cc",
|
||||
"payload_router.h",
|
||||
"report_block_stats.cc",
|
||||
"report_block_stats.h",
|
||||
"stream_synchronization.cc",
|
||||
|
68
webrtc/video_engine/payload_router.cc
Normal file
68
webrtc/video_engine/payload_router.cc
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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/system_wrappers/interface/critical_section_wrapper.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
PayloadRouter::PayloadRouter()
|
||||
: crit_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
active_(false) {}
|
||||
|
||||
PayloadRouter::~PayloadRouter() {}
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
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_size,
|
||||
const RTPFragmentationHeader* fragmentation,
|
||||
const RTPVideoHeader* rtp_video_hdr) {
|
||||
CriticalSectionScoped cs(crit_.get());
|
||||
DCHECK(rtp_video_hdr == NULL ||
|
||||
rtp_video_hdr->simulcastIdx <= rtp_modules_.size());
|
||||
|
||||
if (!active_ || rtp_modules_.empty())
|
||||
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_size, fragmentation, rtp_video_hdr) == 0 ? true : false;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
67
webrtc/video_engine/payload_router.h
Normal file
67
webrtc/video_engine/payload_router.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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/thread_annotations.h"
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.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();
|
||||
|
||||
// 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);
|
||||
|
||||
private:
|
||||
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());
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PayloadRouter);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_VIDEO_ENGINE_PAYLOAD_ROUTER_H_
|
131
webrtc/video_engine/payload_router_unittest.cc
Normal file
131
webrtc/video_engine/payload_router_unittest.cc
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.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());
|
||||
}
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
} // namespace webrtc
|
@ -49,6 +49,7 @@
|
||||
'call_stats.h',
|
||||
'encoder_state_feedback.h',
|
||||
'overuse_frame_detector.h',
|
||||
'payload_router.h',
|
||||
'report_block_stats.h',
|
||||
'stream_synchronization.h',
|
||||
'vie_base_impl.h',
|
||||
@ -83,6 +84,7 @@
|
||||
'call_stats.cc',
|
||||
'encoder_state_feedback.cc',
|
||||
'overuse_frame_detector.cc',
|
||||
'payload_router.cc',
|
||||
'report_block_stats.cc',
|
||||
'stream_synchronization.cc',
|
||||
'vie_base_impl.cc',
|
||||
@ -134,6 +136,7 @@
|
||||
'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_capturer_unittest.cc',
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "webrtc/video_engine/include/vie_errors.h"
|
||||
#include "webrtc/video_engine/include/vie_image_process.h"
|
||||
#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
|
||||
#include "webrtc/video_engine/payload_router.h"
|
||||
#include "webrtc/video_engine/report_block_stats.h"
|
||||
#include "webrtc/video_engine/vie_defines.h"
|
||||
|
||||
@ -79,6 +80,7 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
||||
callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
default_rtp_rtcp_(default_rtp_rtcp),
|
||||
send_payload_router_(new PayloadRouter()),
|
||||
vcm_(VideoCodingModule::Create()),
|
||||
vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
|
||||
vie_sender_(channel_id),
|
||||
@ -131,6 +133,11 @@ int32_t ViEChannel::Init() {
|
||||
if (paced_sender_) {
|
||||
rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||
}
|
||||
if (sender_) {
|
||||
std::list<RtpRtcp*> send_rtp_modules(1, rtp_rtcp_.get());
|
||||
send_payload_router_->SetSendingRtpModules(send_rtp_modules);
|
||||
send_payload_router_->set_active(true);
|
||||
}
|
||||
if (vcm_->InitializeReceiver() != 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -173,6 +180,7 @@ ViEChannel::~ViEChannel() {
|
||||
module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
|
||||
module_process_thread_.DeRegisterModule(vcm_);
|
||||
module_process_thread_.DeRegisterModule(&vie_sync_);
|
||||
send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>());
|
||||
while (simulcast_rtp_rtcp_.size() > 0) {
|
||||
std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
|
||||
RtpRtcp* rtp_rtcp = *it;
|
||||
@ -322,6 +330,9 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
// Stop and Start the RTP module -> trigger new SSRC, if an SSRC hasn't been
|
||||
// set explicitly.
|
||||
bool restart_rtp = false;
|
||||
bool router_was_active = send_payload_router_->active();
|
||||
send_payload_router_->set_active(false);
|
||||
send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>());
|
||||
if (rtp_rtcp_->Sending() && new_stream) {
|
||||
restart_rtp = true;
|
||||
rtp_rtcp_->SetSendingStatus(false);
|
||||
@ -480,6 +491,16 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
(*it)->SetSendingMediaStatus(true);
|
||||
}
|
||||
}
|
||||
// Update the packet router with the sending RTP RTCP modules.
|
||||
std::list<RtpRtcp*> active_send_modules;
|
||||
active_send_modules.push_back(rtp_rtcp_.get());
|
||||
for (std::list<RtpRtcp*>::const_iterator cit = simulcast_rtp_rtcp_.begin();
|
||||
cit != simulcast_rtp_rtcp_.end(); ++cit) {
|
||||
active_send_modules.push_back(*cit);
|
||||
}
|
||||
send_payload_router_->SetSendingRtpModules(active_send_modules);
|
||||
if (router_was_active)
|
||||
send_payload_router_->set_active(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -854,7 +875,6 @@ void ViEChannel::EnableTMMBR(bool enable) {
|
||||
}
|
||||
|
||||
int32_t ViEChannel::EnableKeyFrameRequestCallback(const bool enable) {
|
||||
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
if (enable && !codec_observer_) {
|
||||
LOG(LS_ERROR) << "No ViECodecObserver set.";
|
||||
@ -1344,11 +1364,13 @@ int32_t ViEChannel::StartSend() {
|
||||
rtp_rtcp->SetSendingMediaStatus(true);
|
||||
rtp_rtcp->SetSendingStatus(true);
|
||||
}
|
||||
send_payload_router_->set_active(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ViEChannel::StopSend() {
|
||||
UpdateHistogramsAtStopSend();
|
||||
send_payload_router_->set_active(false);
|
||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||
rtp_rtcp_->SetSendingMediaStatus(false);
|
||||
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
|
||||
@ -1478,6 +1500,10 @@ RtpRtcp* ViEChannel::rtp_rtcp() {
|
||||
return rtp_rtcp_.get();
|
||||
}
|
||||
|
||||
PayloadRouter* ViEChannel::send_payload_router() {
|
||||
return send_payload_router_.get();
|
||||
}
|
||||
|
||||
CallStatsObserver* ViEChannel::GetStatsObserver() {
|
||||
return stats_observer_.get();
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class CriticalSectionWrapper;
|
||||
class EncodedImageCallback;
|
||||
class I420FrameCallback;
|
||||
class PacedSender;
|
||||
class PayloadRouter;
|
||||
class ProcessThread;
|
||||
class ReceiveStatisticsProxy;
|
||||
class ReportBlockStats;
|
||||
@ -301,6 +302,7 @@ class ViEChannel
|
||||
|
||||
// Gets the modules used by the channel.
|
||||
RtpRtcp* rtp_rtcp();
|
||||
PayloadRouter* send_payload_router();
|
||||
|
||||
CallStatsObserver* GetStatsObserver();
|
||||
|
||||
@ -467,6 +469,8 @@ class ViEChannel
|
||||
scoped_ptr<RtpRtcp> rtp_rtcp_;
|
||||
std::list<RtpRtcp*> simulcast_rtp_rtcp_;
|
||||
std::list<RtpRtcp*> removed_rtp_rtcp_;
|
||||
scoped_ptr<PayloadRouter> send_payload_router_;
|
||||
|
||||
VideoCodingModule* const vcm_;
|
||||
ViEReceiver vie_receiver_;
|
||||
ViESender vie_sender_;
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "webrtc/video_engine/vie_channel_manager.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/common.h"
|
||||
#include "webrtc/engine_configurations.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||
@ -114,6 +116,9 @@ int ViEChannelManager::CreateChannel(int* channel_id,
|
||||
delete group;
|
||||
return -1;
|
||||
}
|
||||
// Connect the encoder with the send packet router, to enable sending.
|
||||
vie_encoder->SetSendPayloadRouter(
|
||||
channel_map_[new_channel_id]->send_payload_router());
|
||||
|
||||
// Add ViEEncoder to EncoderFeedBackObserver.
|
||||
unsigned int ssrc = 0;
|
||||
@ -174,6 +179,10 @@ int ViEChannelManager::CreateChannel(int* channel_id,
|
||||
delete vie_encoder;
|
||||
vie_encoder = NULL;
|
||||
}
|
||||
// Connect the encoder with the send packet router, to enable sending.
|
||||
vie_encoder->SetSendPayloadRouter(
|
||||
channel_map_[new_channel_id]->send_payload_router());
|
||||
|
||||
// Register the ViEEncoder to get key frame requests for this channel.
|
||||
unsigned int ssrc = 0;
|
||||
int stream_idx = 0;
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/common_video/interface/video_image.h"
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "webrtc/frame_callback.h"
|
||||
@ -33,6 +34,7 @@
|
||||
#include "webrtc/video/send_statistics_proxy.h"
|
||||
#include "webrtc/video_engine/include/vie_codec.h"
|
||||
#include "webrtc/video_engine/include/vie_image_process.h"
|
||||
#include "webrtc/video_engine/payload_router.h"
|
||||
#include "webrtc/video_engine/vie_defines.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -137,6 +139,7 @@ ViEEncoder::ViEEncoder(int32_t engine_id,
|
||||
vcm_(*webrtc::VideoCodingModule::Create()),
|
||||
vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(engine_id,
|
||||
channel_id))),
|
||||
send_payload_router_(NULL),
|
||||
callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
bitrate_controller_(bitrate_controller),
|
||||
@ -228,6 +231,11 @@ bool ViEEncoder::Init() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViEEncoder::SetSendPayloadRouter(PayloadRouter* send_payload_router) {
|
||||
DCHECK(send_payload_router_ == NULL);
|
||||
send_payload_router_ = send_payload_router;
|
||||
}
|
||||
|
||||
ViEEncoder::~ViEEncoder() {
|
||||
UpdateHistograms();
|
||||
if (bitrate_controller_) {
|
||||
@ -504,8 +512,10 @@ RtpRtcp* ViEEncoder::SendRtpRtcpModule() {
|
||||
void ViEEncoder::DeliverFrame(int id,
|
||||
I420VideoFrame* video_frame,
|
||||
const std::vector<uint32_t>& csrcs) {
|
||||
if (default_rtp_rtcp_->SendingMedia() == false) {
|
||||
// We've paused or we have no channels attached, don't encode.
|
||||
DCHECK(send_payload_router_ != NULL);
|
||||
if (!default_rtp_rtcp_->SendingMedia() || !send_payload_router_->active()) {
|
||||
// We've paused or we have no channels attached, don't waste resources on
|
||||
// encoding.
|
||||
return;
|
||||
}
|
||||
{
|
||||
@ -731,15 +741,17 @@ int32_t ViEEncoder::SendData(
|
||||
const EncodedImage& encoded_image,
|
||||
const webrtc::RTPFragmentationHeader& fragmentation_header,
|
||||
const RTPVideoHeader* rtp_video_hdr) {
|
||||
DCHECK(send_payload_router_ != NULL);
|
||||
|
||||
if (send_statistics_proxy_ != NULL) {
|
||||
send_statistics_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr);
|
||||
}
|
||||
// New encoded data, hand over to the rtp module.
|
||||
return default_rtp_rtcp_->SendOutgoingData(
|
||||
|
||||
return send_payload_router_->RoutePayload(
|
||||
VCMEncodedFrame::ConvertFrameType(encoded_image._frameType), payload_type,
|
||||
encoded_image._timeStamp, encoded_image.capture_time_ms_,
|
||||
encoded_image._buffer, encoded_image._length, &fragmentation_header,
|
||||
rtp_video_hdr);
|
||||
rtp_video_hdr) ? 0 : -1;
|
||||
}
|
||||
|
||||
int32_t ViEEncoder::ProtectionRequest(
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
#include "webrtc/common_types.h"
|
||||
@ -32,6 +33,7 @@ class Config;
|
||||
class CriticalSectionWrapper;
|
||||
class EncodedImageCallback;
|
||||
class PacedSender;
|
||||
class PayloadRouter;
|
||||
class ProcessThread;
|
||||
class QMVideoSettingsCallback;
|
||||
class RtpRtcp;
|
||||
@ -62,6 +64,9 @@ class ViEEncoder
|
||||
|
||||
bool Init();
|
||||
|
||||
// This function is assumed to be called before any frames are delivered.
|
||||
void SetSendPayloadRouter(PayloadRouter* send_payload_router);
|
||||
|
||||
void SetNetworkTransmissionState(bool is_transmitting);
|
||||
|
||||
// Returns the id of the owning channel.
|
||||
@ -201,6 +206,7 @@ class ViEEncoder
|
||||
VideoCodingModule& vcm_;
|
||||
VideoProcessingModule& vpm_;
|
||||
scoped_ptr<RtpRtcp> default_rtp_rtcp_;
|
||||
PayloadRouter* send_payload_router_;
|
||||
scoped_ptr<CriticalSectionWrapper> callback_cs_;
|
||||
scoped_ptr<CriticalSectionWrapper> data_cs_;
|
||||
scoped_ptr<BitrateObserver> bitrate_observer_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user