Remove PayloadRouter dependency from ViEEncoder.
BUG=webrtc:5687 Review-Url: https://codereview.webrtc.org/1912653002 Cr-Commit-Position: refs/heads/master@{#12593}
This commit is contained in:
@ -26,9 +26,11 @@ int32_t EncodedFrameCallbackAdapter::Encoded(
|
||||
const EncodedImage& encodedImage,
|
||||
const CodecSpecificInfo* codecSpecificInfo,
|
||||
const RTPFragmentationHeader* fragmentation) {
|
||||
RTC_DCHECK(observer_);
|
||||
if (!observer_)
|
||||
return 0;
|
||||
const EncodedFrame frame(encodedImage._buffer, encodedImage._length,
|
||||
encodedImage._frameType);
|
||||
|
||||
observer_->EncodedFrameCallback(frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ class EncodedFrameCallbackAdapter : public EncodedImageCallback {
|
||||
const RTPFragmentationHeader* fragmentation);
|
||||
|
||||
private:
|
||||
EncodedFrameObserver* observer_;
|
||||
EncodedFrameObserver* const observer_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@ -32,9 +32,7 @@ class MockVieEncoder : public ViEEncoder {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
pacer,
|
||||
nullptr,
|
||||
nullptr) {}
|
||||
pacer) {}
|
||||
~MockVieEncoder() {}
|
||||
|
||||
MOCK_METHOD1(OnReceivedIntraFrameRequest,
|
||||
|
||||
@ -84,6 +84,7 @@ void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PayloadRouter::PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules,
|
||||
@ -115,10 +116,12 @@ bool PayloadRouter::active() {
|
||||
return active_ && !rtp_modules_.empty();
|
||||
}
|
||||
|
||||
void PayloadRouter::SetSendingRtpModules(size_t num_sending_modules) {
|
||||
RTC_DCHECK_LE(num_sending_modules, rtp_modules_.size());
|
||||
void PayloadRouter::SetSendStreams(const std::vector<VideoStream>& streams) {
|
||||
RTC_DCHECK_LE(streams.size(), rtp_modules_.size());
|
||||
rtc::CritScope lock(&crit_);
|
||||
num_sending_modules_ = num_sending_modules;
|
||||
num_sending_modules_ = streams.size();
|
||||
streams_ = streams;
|
||||
// TODO(perkj): Should SetSendStreams also call SetTargetSendBitrate?
|
||||
UpdateModuleSendingState();
|
||||
}
|
||||
|
||||
@ -163,12 +166,22 @@ int32_t PayloadRouter::Encoded(const EncodedImage& encoded_image,
|
||||
encoded_image._length, fragmentation, &rtp_video_header);
|
||||
}
|
||||
|
||||
void PayloadRouter::SetTargetSendBitrates(
|
||||
const std::vector<uint32_t>& stream_bitrates) {
|
||||
void PayloadRouter::SetTargetSendBitrate(uint32_t bitrate_bps) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
RTC_DCHECK_LE(stream_bitrates.size(), rtp_modules_.size());
|
||||
for (size_t i = 0; i < stream_bitrates.size(); ++i) {
|
||||
rtp_modules_[i]->SetTargetSendBitrate(stream_bitrates[i]);
|
||||
RTC_DCHECK_LE(streams_.size(), rtp_modules_.size());
|
||||
|
||||
// TODO(sprang): Rebase https://codereview.webrtc.org/1913073002/ on top of
|
||||
// this.
|
||||
int bitrate_remainder = bitrate_bps;
|
||||
for (size_t i = 0; i < streams_.size() && bitrate_remainder > 0; ++i) {
|
||||
int stream_bitrate = 0;
|
||||
if (streams_[i].max_bitrate_bps > bitrate_remainder) {
|
||||
stream_bitrate = bitrate_remainder;
|
||||
} else {
|
||||
stream_bitrate = streams_[i].max_bitrate_bps;
|
||||
}
|
||||
bitrate_remainder -= stream_bitrate;
|
||||
rtp_modules_[i]->SetTargetSendBitrate(stream_bitrate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/config.h"
|
||||
#include "webrtc/video_encoder.h"
|
||||
#include "webrtc/system_wrappers/include/atomic32.h"
|
||||
|
||||
@ -36,7 +37,7 @@ class PayloadRouter : public EncodedImageCallback {
|
||||
~PayloadRouter();
|
||||
|
||||
static size_t DefaultMaxPayloadLength();
|
||||
void SetSendingRtpModules(size_t num_sending_modules);
|
||||
void SetSendStreams(const std::vector<VideoStream>& streams);
|
||||
|
||||
// PayloadRouter will only route packets if being active, all packets will be
|
||||
// dropped otherwise.
|
||||
@ -49,9 +50,8 @@ class PayloadRouter : public EncodedImageCallback {
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
const RTPFragmentationHeader* fragmentation) override;
|
||||
|
||||
// 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);
|
||||
// Configures current target bitrate.
|
||||
void SetTargetSendBitrate(uint32_t bitrate_bps);
|
||||
|
||||
// Returns the maximum allowed data payload length, given the configured MTU
|
||||
// and RTP headers.
|
||||
@ -62,6 +62,7 @@ class PayloadRouter : public EncodedImageCallback {
|
||||
|
||||
rtc::CriticalSection crit_;
|
||||
bool active_ GUARDED_BY(crit_);
|
||||
std::vector<VideoStream> streams_ GUARDED_BY(crit_);
|
||||
size_t num_sending_modules_ GUARDED_BY(crit_);
|
||||
|
||||
// Rtp modules are assumed to be sorted in simulcast index order. Not owned.
|
||||
|
||||
@ -25,8 +25,9 @@ using ::testing::Return;
|
||||
namespace webrtc {
|
||||
|
||||
TEST(PayloadRouterTest, SendOnOneModule) {
|
||||
MockRtpRtcp rtp;
|
||||
NiceMock<MockRtpRtcp> rtp;
|
||||
std::vector<RtpRtcp*> modules(1, &rtp);
|
||||
std::vector<VideoStream> streams(1);
|
||||
|
||||
uint8_t payload = 'a';
|
||||
int8_t payload_type = 96;
|
||||
@ -38,7 +39,7 @@ TEST(PayloadRouterTest, SendOnOneModule) {
|
||||
encoded_image._length = 1;
|
||||
|
||||
PayloadRouter payload_router(modules, payload_type);
|
||||
payload_router.SetSendingRtpModules(modules.size());
|
||||
payload_router.SetSendStreams(streams);
|
||||
|
||||
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
|
||||
encoded_image._timeStamp,
|
||||
@ -71,7 +72,8 @@ TEST(PayloadRouterTest, SendOnOneModule) {
|
||||
.Times(1);
|
||||
EXPECT_EQ(0, payload_router.Encoded(encoded_image, nullptr, nullptr));
|
||||
|
||||
payload_router.SetSendingRtpModules(0);
|
||||
streams.clear();
|
||||
payload_router.SetSendStreams(streams);
|
||||
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
|
||||
encoded_image._timeStamp,
|
||||
encoded_image.capture_time_ms_, &payload,
|
||||
@ -81,11 +83,12 @@ TEST(PayloadRouterTest, SendOnOneModule) {
|
||||
}
|
||||
|
||||
TEST(PayloadRouterTest, SendSimulcast) {
|
||||
MockRtpRtcp rtp_1;
|
||||
MockRtpRtcp rtp_2;
|
||||
NiceMock<MockRtpRtcp> rtp_1;
|
||||
NiceMock<MockRtpRtcp> rtp_2;
|
||||
std::vector<RtpRtcp*> modules;
|
||||
modules.push_back(&rtp_1);
|
||||
modules.push_back(&rtp_2);
|
||||
std::vector<VideoStream> streams(2);
|
||||
|
||||
int8_t payload_type = 96;
|
||||
uint8_t payload = 'a';
|
||||
@ -97,7 +100,7 @@ TEST(PayloadRouterTest, SendSimulcast) {
|
||||
encoded_image._length = 1;
|
||||
|
||||
PayloadRouter payload_router(modules, payload_type);
|
||||
payload_router.SetSendingRtpModules(modules.size());
|
||||
payload_router.SetSendStreams(streams);
|
||||
|
||||
CodecSpecificInfo codec_info_1;
|
||||
memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
|
||||
@ -138,7 +141,8 @@ TEST(PayloadRouterTest, SendSimulcast) {
|
||||
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, &codec_info_2, nullptr));
|
||||
|
||||
// Invalid simulcast index.
|
||||
payload_router.SetSendingRtpModules(1);
|
||||
streams.pop_back(); // Remove a stream.
|
||||
payload_router.SetSendStreams(streams);
|
||||
payload_router.set_active(true);
|
||||
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
|
||||
.Times(0);
|
||||
@ -152,15 +156,16 @@ TEST(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;
|
||||
MockRtpRtcp rtp_1;
|
||||
MockRtpRtcp rtp_2;
|
||||
NiceMock<MockRtpRtcp> rtp_1;
|
||||
NiceMock<MockRtpRtcp> rtp_2;
|
||||
std::vector<RtpRtcp*> modules;
|
||||
modules.push_back(&rtp_1);
|
||||
modules.push_back(&rtp_2);
|
||||
PayloadRouter payload_router(modules, 42);
|
||||
|
||||
EXPECT_EQ(kDefaultMaxLength, PayloadRouter::DefaultMaxPayloadLength());
|
||||
payload_router.SetSendingRtpModules(modules.size());
|
||||
std::vector<VideoStream> streams(2);
|
||||
payload_router.SetSendStreams(streams);
|
||||
|
||||
// Modules return a higher length than the default value.
|
||||
EXPECT_CALL(rtp_1, MaxDataPayloadLength())
|
||||
@ -183,29 +188,23 @@ TEST(PayloadRouterTest, MaxPayloadLength) {
|
||||
}
|
||||
|
||||
TEST(PayloadRouterTest, SetTargetSendBitrates) {
|
||||
MockRtpRtcp rtp_1;
|
||||
MockRtpRtcp rtp_2;
|
||||
NiceMock<MockRtpRtcp> rtp_1;
|
||||
NiceMock<MockRtpRtcp> rtp_2;
|
||||
std::vector<RtpRtcp*> modules;
|
||||
modules.push_back(&rtp_1);
|
||||
modules.push_back(&rtp_2);
|
||||
PayloadRouter payload_router(modules, 42);
|
||||
payload_router.SetSendingRtpModules(modules.size());
|
||||
std::vector<VideoStream> streams(2);
|
||||
streams[0].max_bitrate_bps = 10000;
|
||||
streams[1].max_bitrate_bps = 100000;
|
||||
payload_router.SetSendStreams(streams);
|
||||
|
||||
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(1);
|
||||
EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
|
||||
.Times(0);
|
||||
payload_router.SetTargetSendBitrates(bitrates);
|
||||
payload_router.SetTargetSendBitrate(bitrate_1 + bitrate_2);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -372,16 +372,13 @@ VideoSendStream::VideoSendStream(
|
||||
this,
|
||||
config.post_encode_callback,
|
||||
&stats_proxy_),
|
||||
vie_encoder_(
|
||||
num_cpu_cores,
|
||||
config_.rtp.ssrcs,
|
||||
module_process_thread_,
|
||||
&stats_proxy_,
|
||||
config.pre_encode_callback,
|
||||
&overuse_detector_,
|
||||
congestion_controller_->pacer(),
|
||||
&payload_router_,
|
||||
config.post_encode_callback ? &encoded_frame_proxy_ : nullptr),
|
||||
vie_encoder_(num_cpu_cores,
|
||||
config_.rtp.ssrcs,
|
||||
module_process_thread_,
|
||||
&stats_proxy_,
|
||||
config.pre_encode_callback,
|
||||
&overuse_detector_,
|
||||
congestion_controller_->pacer()),
|
||||
video_sender_(vie_encoder_.video_sender()),
|
||||
bandwidth_observer_(congestion_controller_->GetBitrateController()
|
||||
->CreateRtcpBandwidthObserver()),
|
||||
@ -516,18 +513,17 @@ void VideoSendStream::Start() {
|
||||
if (payload_router_.active())
|
||||
return;
|
||||
TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
|
||||
vie_encoder_.Pause();
|
||||
payload_router_.set_active(true);
|
||||
// Was not already started, trigger a keyframe.
|
||||
vie_encoder_.SendKeyFrame();
|
||||
vie_encoder_.Restart();
|
||||
vie_encoder_.Start();
|
||||
}
|
||||
|
||||
void VideoSendStream::Stop() {
|
||||
if (!payload_router_.active())
|
||||
return;
|
||||
TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
|
||||
// TODO(pbos): Make sure the encoder stops here.
|
||||
vie_encoder_.Pause();
|
||||
payload_router_.set_active(false);
|
||||
}
|
||||
|
||||
@ -565,8 +561,11 @@ void VideoSendStream::EncoderProcess() {
|
||||
this, encoder_settings->video_codec.minBitrate * 1000,
|
||||
encoder_settings->video_codec.maxBitrate * 1000) /
|
||||
1000;
|
||||
|
||||
payload_router_.SetSendStreams(encoder_settings->streams);
|
||||
vie_encoder_.SetEncoder(encoder_settings->video_codec,
|
||||
encoder_settings->min_transmit_bitrate_bps);
|
||||
encoder_settings->min_transmit_bitrate_bps,
|
||||
payload_router_.MaxPayloadLength(), this);
|
||||
if (config_.suspend_below_min_bitrate) {
|
||||
video_sender_->SuspendBelowMinBitrate();
|
||||
bitrate_allocator_->EnforceMinBitrate(false);
|
||||
@ -596,7 +595,7 @@ void VideoSendStream::ReconfigureVideoEncoder(
|
||||
{
|
||||
rtc::CritScope lock(&encoder_settings_crit_);
|
||||
pending_encoder_settings_ = rtc::Optional<EncoderSettings>(
|
||||
{video_codec, config.min_transmit_bitrate_bps});
|
||||
{video_codec, config.min_transmit_bitrate_bps, config.streams});
|
||||
}
|
||||
encoder_wakeup_event_.Set();
|
||||
}
|
||||
@ -615,6 +614,16 @@ void VideoSendStream::NormalUsage() {
|
||||
config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
|
||||
}
|
||||
|
||||
int32_t VideoSendStream::Encoded(const EncodedImage& encoded_image,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
const RTPFragmentationHeader* fragmentation) {
|
||||
// |encoded_frame_proxy_| forwards frames to |config_.post_encode_callback|;
|
||||
encoded_frame_proxy_.Encoded(encoded_image, codec_specific_info,
|
||||
fragmentation);
|
||||
return payload_router_.Encoded(encoded_image, codec_specific_info,
|
||||
fragmentation);
|
||||
}
|
||||
|
||||
void VideoSendStream::ConfigureProtection() {
|
||||
// Enable NACK, FEC or both.
|
||||
const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
|
||||
@ -736,6 +745,7 @@ int VideoSendStream::GetPaddingNeededBps() const {
|
||||
void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) {
|
||||
payload_router_.SetTargetSendBitrate(bitrate_bps);
|
||||
vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
|
||||
}
|
||||
|
||||
|
||||
@ -49,7 +49,8 @@ namespace internal {
|
||||
class VideoSendStream : public webrtc::VideoSendStream,
|
||||
public webrtc::CpuOveruseObserver,
|
||||
public webrtc::BitrateAllocatorObserver,
|
||||
public webrtc::VCMProtectionCallback {
|
||||
public webrtc::VCMProtectionCallback,
|
||||
protected webrtc::EncodedImageCallback {
|
||||
public:
|
||||
VideoSendStream(int num_cpu_cores,
|
||||
ProcessThread* module_process_thread,
|
||||
@ -98,7 +99,16 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
struct EncoderSettings {
|
||||
VideoCodec video_codec;
|
||||
int min_transmit_bitrate_bps;
|
||||
std::vector<VideoStream> streams;
|
||||
};
|
||||
|
||||
// Implements EncodedImageCallback. The implementation routes encoded frames
|
||||
// to the |payload_router_| and |config.pre_encode_callback| if set.
|
||||
// Called on an arbitrary encoder callback thread.
|
||||
int32_t Encoded(const EncodedImage& encoded_image,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
const RTPFragmentationHeader* fragmentation) override;
|
||||
|
||||
static bool EncoderThreadFunction(void* obj);
|
||||
void EncoderProcess();
|
||||
|
||||
|
||||
@ -38,28 +38,6 @@ namespace webrtc {
|
||||
static const float kStopPaddingThresholdMs = 2000;
|
||||
static const int kMinKeyFrameRequestIntervalMs = 300;
|
||||
|
||||
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(VideoProcessing* vpm);
|
||||
@ -81,9 +59,7 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores,
|
||||
SendStatisticsProxy* stats_proxy,
|
||||
rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
|
||||
OveruseFrameDetector* overuse_detector,
|
||||
PacedSender* pacer,
|
||||
PayloadRouter* payload_router,
|
||||
EncodedImageCallback* post_encode_callback)
|
||||
PacedSender* pacer)
|
||||
: number_of_cores_(number_of_cores),
|
||||
ssrcs_(ssrcs),
|
||||
vp_(VideoProcessing::Create()),
|
||||
@ -93,14 +69,12 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores,
|
||||
pre_encode_callback_(pre_encode_callback),
|
||||
overuse_detector_(overuse_detector),
|
||||
pacer_(pacer),
|
||||
send_payload_router_(payload_router),
|
||||
post_encode_callback_(post_encode_callback),
|
||||
time_of_last_frame_activity_ms_(0),
|
||||
encoder_config_(),
|
||||
min_transmit_bitrate_bps_(0),
|
||||
last_observed_bitrate_bps_(0),
|
||||
network_is_transmitting_(true),
|
||||
encoder_paused_(false),
|
||||
encoder_paused_(true),
|
||||
encoder_paused_and_dropped_frame_(false),
|
||||
time_last_intra_request_ms_(ssrcs.size(), -1),
|
||||
module_process_thread_(module_process_thread),
|
||||
@ -149,7 +123,7 @@ void ViEEncoder::Pause() {
|
||||
encoder_paused_ = true;
|
||||
}
|
||||
|
||||
void ViEEncoder::Restart() {
|
||||
void ViEEncoder::Start() {
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
encoder_paused_ = false;
|
||||
}
|
||||
@ -166,8 +140,9 @@ int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) {
|
||||
return 0;
|
||||
}
|
||||
void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec,
|
||||
int min_transmit_bitrate_bps) {
|
||||
RTC_DCHECK(send_payload_router_);
|
||||
int min_transmit_bitrate_bps,
|
||||
size_t max_data_payload_length,
|
||||
EncodedImageCallback* sink) {
|
||||
// Setting target width and height for VPM.
|
||||
RTC_CHECK_EQ(VPM_OK,
|
||||
vp_->SetTargetResolution(video_codec.width, video_codec.height,
|
||||
@ -178,11 +153,13 @@ void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec,
|
||||
{
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
encoder_config_ = video_codec;
|
||||
encoder_paused_ = true;
|
||||
min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
|
||||
}
|
||||
{
|
||||
rtc::CritScope lock(&sink_cs_);
|
||||
sink_ = sink;
|
||||
}
|
||||
|
||||
size_t max_data_payload_length = send_payload_router_->MaxPayloadLength();
|
||||
bool success = video_sender_.RegisterSendCodec(
|
||||
&video_codec, number_of_cores_,
|
||||
static_cast<uint32_t>(max_data_payload_length)) == VCM_OK;
|
||||
@ -191,11 +168,6 @@ void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec,
|
||||
RTC_DCHECK(success);
|
||||
}
|
||||
|
||||
send_payload_router_->SetSendingRtpModules(
|
||||
video_codec.numberOfSimulcastStreams);
|
||||
|
||||
// Restart the media flow
|
||||
Restart();
|
||||
if (stats_proxy_) {
|
||||
// Clear stats for disabled layers.
|
||||
for (size_t i = video_codec.numberOfSimulcastStreams; i < ssrcs_.size();
|
||||
@ -307,11 +279,6 @@ void ViEEncoder::TraceFrameDropEnd() {
|
||||
}
|
||||
|
||||
void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) {
|
||||
if (!send_payload_router_->active()) {
|
||||
// We've paused or we have no channels attached, don't waste resources on
|
||||
// encoding.
|
||||
return;
|
||||
}
|
||||
VideoCodecType codec_type;
|
||||
{
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
@ -394,25 +361,21 @@ void ViEEncoder::OnEncoderImplementationName(const char* implementation_name) {
|
||||
int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
const RTPFragmentationHeader* fragmentation) {
|
||||
RTC_DCHECK(send_payload_router_);
|
||||
|
||||
{
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp();
|
||||
}
|
||||
|
||||
if (post_encode_callback_) {
|
||||
post_encode_callback_->Encoded(encoded_image, codec_specific_info,
|
||||
fragmentation);
|
||||
}
|
||||
|
||||
if (stats_proxy_) {
|
||||
stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info);
|
||||
}
|
||||
int success = send_payload_router_->Encoded(
|
||||
encoded_image, codec_specific_info, fragmentation);
|
||||
overuse_detector_->FrameSent(encoded_image._timeStamp);
|
||||
|
||||
int success = 0;
|
||||
{
|
||||
rtc::CritScope lock(&sink_cs_);
|
||||
success = sink_->Encoded(encoded_image, codec_specific_info, fragmentation);
|
||||
}
|
||||
|
||||
overuse_detector_->FrameSent(encoded_image._timeStamp);
|
||||
if (kEnableFrameRecording) {
|
||||
int layer = codec_specific_info->codecType == kVideoCodecVP8
|
||||
? codec_specific_info->codecSpecific.VP8.simulcastIdx
|
||||
@ -489,26 +452,17 @@ void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate" << bitrate_bps
|
||||
<< " packet loss " << static_cast<int>(fraction_lost)
|
||||
<< " rtt " << round_trip_time_ms;
|
||||
RTC_DCHECK(send_payload_router_);
|
||||
video_sender_.SetChannelParameters(bitrate_bps, fraction_lost,
|
||||
round_trip_time_ms);
|
||||
bool video_is_suspended = video_sender_.VideoSuspended();
|
||||
bool video_suspension_changed;
|
||||
VideoCodec send_codec;
|
||||
{
|
||||
rtc::CritScope lock(&data_cs_);
|
||||
last_observed_bitrate_bps_ = bitrate_bps;
|
||||
video_suspension_changed = video_suspended_ != video_is_suspended;
|
||||
video_suspended_ = video_is_suspended;
|
||||
send_codec = encoder_config_;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!video_suspension_changed)
|
||||
return;
|
||||
// Video suspend-state changed, inform codec observer.
|
||||
|
||||
@ -33,7 +33,6 @@ class Config;
|
||||
class EncodedImageCallback;
|
||||
class OveruseFrameDetector;
|
||||
class PacedSender;
|
||||
class PayloadRouter;
|
||||
class ProcessThread;
|
||||
class QMVideoSettingsCallback;
|
||||
class SendStatisticsProxy;
|
||||
@ -41,6 +40,16 @@ class ViEBitrateObserver;
|
||||
class ViEEffectFilter;
|
||||
class VideoEncoder;
|
||||
|
||||
// VieEncoder represent a video encoder that accepts raw video frames as input
|
||||
// and produces an encoded bit stream.
|
||||
// Usage:
|
||||
// 1. Instantiate
|
||||
// 2. Call Init
|
||||
// 3. Call RegisterExternalEncoder if available.
|
||||
// 4. Call SetEncoder with the codec settings and the object that shall receive
|
||||
// the encoded bit stream.
|
||||
// 5. Call Start.
|
||||
// 6. For each available raw video frame call EncodeVideoFrame.
|
||||
class ViEEncoder : public VideoEncoderRateObserver,
|
||||
public EncodedImageCallback,
|
||||
public VCMPacketizationCallback,
|
||||
@ -55,9 +64,7 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
// TODO(nisse): Used only for tests, delete?
|
||||
rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
|
||||
OveruseFrameDetector* overuse_detector,
|
||||
PacedSender* pacer,
|
||||
PayloadRouter* payload_router,
|
||||
EncodedImageCallback* post_encode_callback);
|
||||
PacedSender* pacer);
|
||||
~ViEEncoder();
|
||||
|
||||
bool Init();
|
||||
@ -69,16 +76,19 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
// Returns the id of the owning channel.
|
||||
int Owner() const;
|
||||
|
||||
void Start();
|
||||
// Drops incoming packets before they get to the encoder.
|
||||
void Pause();
|
||||
void Restart();
|
||||
|
||||
// Codec settings.
|
||||
int32_t RegisterExternalEncoder(VideoEncoder* encoder,
|
||||
uint8_t pl_type,
|
||||
bool internal_source);
|
||||
int32_t DeRegisterExternalEncoder(uint8_t pl_type);
|
||||
void SetEncoder(const VideoCodec& video_codec, int min_transmit_bitrate_bps);
|
||||
void SetEncoder(const VideoCodec& video_codec,
|
||||
int min_transmit_bitrate_bps,
|
||||
size_t max_data_payload_length,
|
||||
EncodedImageCallback* sink);
|
||||
|
||||
void EncodeVideoFrame(const VideoFrame& video_frame);
|
||||
void SendKeyFrame();
|
||||
@ -136,8 +146,6 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
rtc::VideoSinkInterface<VideoFrame>* const pre_encode_callback_;
|
||||
OveruseFrameDetector* const overuse_detector_;
|
||||
PacedSender* const pacer_;
|
||||
PayloadRouter* const send_payload_router_;
|
||||
EncodedImageCallback* const post_encode_callback_;
|
||||
|
||||
// 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
|
||||
@ -151,6 +159,9 @@ class ViEEncoder : public VideoEncoderRateObserver,
|
||||
bool encoder_paused_and_dropped_frame_ GUARDED_BY(data_cs_);
|
||||
std::vector<int64_t> time_last_intra_request_ms_ GUARDED_BY(data_cs_);
|
||||
|
||||
rtc::CriticalSection sink_cs_;
|
||||
EncodedImageCallback* sink_ GUARDED_BY(sink_cs_);
|
||||
|
||||
ProcessThread* module_process_thread_;
|
||||
|
||||
bool has_received_sli_ GUARDED_BY(data_cs_);
|
||||
|
||||
Reference in New Issue
Block a user