diff --git a/webrtc/video/encoded_frame_callback_adapter.cc b/webrtc/video/encoded_frame_callback_adapter.cc index 84283608a0..974149170a 100644 --- a/webrtc/video/encoded_frame_callback_adapter.cc +++ b/webrtc/video/encoded_frame_callback_adapter.cc @@ -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; } diff --git a/webrtc/video/encoded_frame_callback_adapter.h b/webrtc/video/encoded_frame_callback_adapter.h index fa824953c1..83fe4bd318 100644 --- a/webrtc/video/encoded_frame_callback_adapter.h +++ b/webrtc/video/encoded_frame_callback_adapter.h @@ -27,7 +27,7 @@ class EncodedFrameCallbackAdapter : public EncodedImageCallback { const RTPFragmentationHeader* fragmentation); private: - EncodedFrameObserver* observer_; + EncodedFrameObserver* const observer_; }; } // namespace internal diff --git a/webrtc/video/encoder_state_feedback_unittest.cc b/webrtc/video/encoder_state_feedback_unittest.cc index 3b7ef29d00..fff5ca82d8 100644 --- a/webrtc/video/encoder_state_feedback_unittest.cc +++ b/webrtc/video/encoder_state_feedback_unittest.cc @@ -32,9 +32,7 @@ class MockVieEncoder : public ViEEncoder { nullptr, nullptr, nullptr, - pacer, - nullptr, - nullptr) {} + pacer) {} ~MockVieEncoder() {} MOCK_METHOD1(OnReceivedIntraFrameRequest, diff --git a/webrtc/video/payload_router.cc b/webrtc/video/payload_router.cc index abe476f276..3be5882cdb 100644 --- a/webrtc/video/payload_router.cc +++ b/webrtc/video/payload_router.cc @@ -84,6 +84,7 @@ void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) { return; } } + } // namespace PayloadRouter::PayloadRouter(const std::vector& 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& 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& 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); } } diff --git a/webrtc/video/payload_router.h b/webrtc/video/payload_router.h index c2f4b0442c..ce65bae6f8 100644 --- a/webrtc/video/payload_router.h +++ b/webrtc/video/payload_router.h @@ -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& 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& 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 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. diff --git a/webrtc/video/payload_router_unittest.cc b/webrtc/video/payload_router_unittest.cc index 41e173bf5f..5b6612124c 100644 --- a/webrtc/video/payload_router_unittest.cc +++ b/webrtc/video/payload_router_unittest.cc @@ -25,8 +25,9 @@ using ::testing::Return; namespace webrtc { TEST(PayloadRouterTest, SendOnOneModule) { - MockRtpRtcp rtp; + NiceMock rtp; std::vector modules(1, &rtp); + std::vector 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 rtp_1; + NiceMock rtp_2; std::vector modules; modules.push_back(&rtp_1); modules.push_back(&rtp_2); + std::vector 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 rtp_1; + NiceMock rtp_2; std::vector 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 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 rtp_1; + NiceMock rtp_2; std::vector modules; modules.push_back(&rtp_1); modules.push_back(&rtp_2); PayloadRouter payload_router(modules, 42); - payload_router.SetSendingRtpModules(modules.size()); + std::vector 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 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 diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index cecc7e9b39..9e38384381 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -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( - {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); } diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h index fb16b67aaa..ead1abfc70 100644 --- a/webrtc/video/video_send_stream.h +++ b/webrtc/video/video_send_stream.h @@ -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 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(); diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc index b0f62724ef..89cbb5285f 100644 --- a/webrtc/video/vie_encoder.cc +++ b/webrtc/video/vie_encoder.cc @@ -38,28 +38,6 @@ namespace webrtc { static const float kStopPaddingThresholdMs = 2000; static const int kMinKeyFrameRequestIntervalMs = 300; -std::vector AllocateStreamBitrates( - uint32_t total_bitrate, - const SimulcastStream* stream_configs, - size_t number_of_streams) { - if (number_of_streams == 0) { - std::vector stream_bitrates(1, 0); - stream_bitrates[0] = total_bitrate; - return stream_bitrates; - } - std::vector 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* 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(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(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 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. diff --git a/webrtc/video/vie_encoder.h b/webrtc/video/vie_encoder.h index d3ac0f945f..3d05a157e7 100644 --- a/webrtc/video/vie_encoder.h +++ b/webrtc/video/vie_encoder.h @@ -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* 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* 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 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_);