| Index: webrtc/video/video_send_stream.cc
|
| diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
|
| index e9654dd29367449f6247e4350d6b54b9ef4de173..c8541fed12105b302a9e27d1403fac2d7ec5bb08 100644
|
| --- a/webrtc/video/video_send_stream.cc
|
| +++ b/webrtc/video/video_send_stream.cc
|
| @@ -202,23 +202,23 @@ bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name) {
|
| return false;
|
| }
|
|
|
| -int CalculateMaxPadBitrateBps(const VideoEncoderConfig& config,
|
| +int CalculateMaxPadBitrateBps(std::vector<VideoStream> streams,
|
| + int min_transmit_bitrate_bps,
|
| bool pad_to_min_bitrate) {
|
| int pad_up_to_bitrate_bps = 0;
|
| // Calculate max padding bitrate for a multi layer codec.
|
| - if (config.streams.size() > 1) {
|
| + if (streams.size() > 1) {
|
| // Pad to min bitrate of the highest layer.
|
| - pad_up_to_bitrate_bps =
|
| - config.streams[config.streams.size() - 1].min_bitrate_bps;
|
| + pad_up_to_bitrate_bps = streams[streams.size() - 1].min_bitrate_bps;
|
| // Add target_bitrate_bps of the lower layers.
|
| - for (size_t i = 0; i < config.streams.size() - 1; ++i)
|
| - pad_up_to_bitrate_bps += config.streams[i].target_bitrate_bps;
|
| + for (size_t i = 0; i < streams.size() - 1; ++i)
|
| + pad_up_to_bitrate_bps += streams[i].target_bitrate_bps;
|
| } else if (pad_to_min_bitrate) {
|
| - pad_up_to_bitrate_bps = config.streams[0].min_bitrate_bps;
|
| + pad_up_to_bitrate_bps = streams[0].min_bitrate_bps;
|
| }
|
|
|
| pad_up_to_bitrate_bps =
|
| - std::max(pad_up_to_bitrate_bps, config.min_transmit_bitrate_bps);
|
| + std::max(pad_up_to_bitrate_bps, min_transmit_bitrate_bps);
|
|
|
| return pad_up_to_bitrate_bps;
|
| }
|
| @@ -236,7 +236,7 @@ namespace internal {
|
| // arbitrary thread.
|
| class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
| public webrtc::VCMProtectionCallback,
|
| - public EncodedImageCallback {
|
| + public ViEEncoder::EncoderSink {
|
| public:
|
| VideoSendStreamImpl(SendStatisticsProxy* stats_proxy,
|
| rtc::TaskQueue* worker_queue,
|
| @@ -248,6 +248,7 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
| ViEEncoder* vie_encoder,
|
| RtcEventLog* event_log,
|
| const VideoSendStream::Config* config,
|
| + int initial_encoder_max_bitrate,
|
| std::map<uint32_t, RtpState> suspended_ssrcs);
|
| ~VideoSendStreamImpl() override;
|
|
|
| @@ -264,11 +265,11 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
| void Start();
|
| void Stop();
|
|
|
| - void SignalEncoderConfigurationChanged(const VideoEncoderConfig& config);
|
| VideoSendStream::RtpStateMap GetRtpStates() const;
|
|
|
| private:
|
| class CheckEncoderActivityTask;
|
| + class EncoderReconfiguredTask;
|
|
|
| // Implements BitrateAllocatorObserver.
|
| uint32_t OnBitrateUpdated(uint32_t bitrate_bps,
|
| @@ -282,6 +283,9 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
| uint32_t* sent_nack_rate_bps,
|
| uint32_t* sent_fec_rate_bps) override;
|
|
|
| + void OnEncoderConfigurationChanged(std::vector<VideoStream> streams,
|
| + int min_transmit_bitrate_bps) override;
|
| +
|
| // 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.
|
| @@ -306,6 +310,7 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
|
| rtc::CriticalSection encoder_activity_crit_sect_;
|
| CheckEncoderActivityTask* check_encoder_activity_task_
|
| GUARDED_BY(encoder_activity_crit_sect_);
|
| +
|
| CallStats* const call_stats_;
|
| CongestionController* const congestion_controller_;
|
| BitrateAllocator* const bitrate_allocator_;
|
| @@ -346,6 +351,7 @@ class VideoSendStream::ConstructionTask : public rtc::QueuedTask {
|
| VieRemb* remb,
|
| RtcEventLog* event_log,
|
| const VideoSendStream::Config* config,
|
| + int initial_encoder_max_bitrate,
|
| const std::map<uint32_t, RtpState>& suspended_ssrcs)
|
| : send_stream_(send_stream),
|
| done_event_(done_event),
|
| @@ -358,6 +364,7 @@ class VideoSendStream::ConstructionTask : public rtc::QueuedTask {
|
| remb_(remb),
|
| event_log_(event_log),
|
| config_(config),
|
| + initial_encoder_max_bitrate_(initial_encoder_max_bitrate),
|
| suspended_ssrcs_(suspended_ssrcs) {}
|
|
|
| ~ConstructionTask() override { done_event_->Set(); }
|
| @@ -367,7 +374,8 @@ class VideoSendStream::ConstructionTask : public rtc::QueuedTask {
|
| send_stream_->reset(new VideoSendStreamImpl(
|
| stats_proxy_, rtc::TaskQueue::Current(), call_stats_,
|
| congestion_controller_, bitrate_allocator_, send_delay_stats_, remb_,
|
| - vie_encoder_, event_log_, config_, std::move(suspended_ssrcs_)));
|
| + vie_encoder_, event_log_, config_, initial_encoder_max_bitrate_,
|
| + std::move(suspended_ssrcs_)));
|
| return true;
|
| }
|
|
|
| @@ -382,6 +390,7 @@ class VideoSendStream::ConstructionTask : public rtc::QueuedTask {
|
| VieRemb* const remb_;
|
| RtcEventLog* const event_log_;
|
| const VideoSendStream::Config* config_;
|
| + int initial_encoder_max_bitrate_;
|
| std::map<uint32_t, RtpState> suspended_ssrcs_;
|
| };
|
|
|
| @@ -461,20 +470,25 @@ class VideoSendStreamImpl::CheckEncoderActivityTask : public rtc::QueuedTask {
|
| bool timed_out_;
|
| };
|
|
|
| -class ReconfigureVideoEncoderTask : public rtc::QueuedTask {
|
| +class VideoSendStreamImpl::EncoderReconfiguredTask : public rtc::QueuedTask {
|
| public:
|
| - ReconfigureVideoEncoderTask(VideoSendStreamImpl* send_stream,
|
| - VideoEncoderConfig config)
|
| - : send_stream_(send_stream), config_(std::move(config)) {}
|
| + EncoderReconfiguredTask(VideoSendStreamImpl* send_stream,
|
| + std::vector<VideoStream> streams,
|
| + int min_transmit_bitrate_bps)
|
| + : send_stream_(send_stream),
|
| + streams_(std::move(streams)),
|
| + min_transmit_bitrate_bps_(min_transmit_bitrate_bps) {}
|
|
|
| private:
|
| bool Run() override {
|
| - send_stream_->SignalEncoderConfigurationChanged(std::move(config_));
|
| + send_stream_->OnEncoderConfigurationChanged(std::move(streams_),
|
| + min_transmit_bitrate_bps_);
|
| return true;
|
| }
|
|
|
| VideoSendStreamImpl* send_stream_;
|
| - VideoEncoderConfig config_;
|
| + std::vector<VideoStream> streams_;
|
| + int min_transmit_bitrate_bps_;
|
| };
|
|
|
| VideoSendStream::VideoSendStream(
|
| @@ -501,11 +515,18 @@ VideoSendStream::VideoSendStream(
|
| config_.pre_encode_callback, config_.overuse_callback,
|
| config_.post_encode_callback));
|
|
|
| + // TODO(perkj): Remove vector<VideoStreams> from VideoEncoderConfig and
|
| + // replace with max_bitrate. The VideoStream should be created by ViEEncoder
|
| + // when the video resolution is known.
|
| + int initial_max_encoder_bitrate = 0;
|
| + for (const auto& stream : encoder_config.streams)
|
| + initial_max_encoder_bitrate += stream.max_bitrate_bps;
|
| +
|
| worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(new ConstructionTask(
|
| &send_stream_, &thread_sync_event_, &stats_proxy_, vie_encoder_.get(),
|
| module_process_thread, call_stats, congestion_controller,
|
| bitrate_allocator, send_delay_stats, remb, event_log, &config_,
|
| - suspended_ssrcs)));
|
| + initial_max_encoder_bitrate, suspended_ssrcs)));
|
|
|
| // Wait for ConstructionTask to complete so that |send_stream_| can be used.
|
| // |module_process_thread| must be registered and deregistered on the thread
|
| @@ -558,10 +579,8 @@ void VideoSendStream::ReconfigureVideoEncoder(VideoEncoderConfig config) {
|
| // TODO(perkj): Move logic for reconfiguration the encoder due to frame size
|
| // change from WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame to
|
| // be internally handled by ViEEncoder.
|
| - vie_encoder_->ConfigureEncoder(config, config_.rtp.max_packet_size);
|
| -
|
| - worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(
|
| - new ReconfigureVideoEncoderTask(send_stream_.get(), std::move(config))));
|
| + vie_encoder_->ConfigureEncoder(std::move(config),
|
| + config_.rtp.max_packet_size);
|
| }
|
|
|
| VideoSendStream::Stats VideoSendStream::GetStats() {
|
| @@ -607,6 +626,7 @@ VideoSendStreamImpl::VideoSendStreamImpl(
|
| ViEEncoder* vie_encoder,
|
| RtcEventLog* event_log,
|
| const VideoSendStream::Config* config,
|
| + int initial_encoder_max_bitrate,
|
| std::map<uint32_t, RtpState> suspended_ssrcs)
|
| : stats_proxy_(stats_proxy),
|
| config_(config),
|
| @@ -620,7 +640,7 @@ VideoSendStreamImpl::VideoSendStreamImpl(
|
| remb_(remb),
|
| max_padding_bitrate_(0),
|
| encoder_min_bitrate_bps_(0),
|
| - encoder_max_bitrate_bps_(0),
|
| + encoder_max_bitrate_bps_(initial_encoder_max_bitrate),
|
| encoder_target_rate_bps_(0),
|
| vie_encoder_(vie_encoder),
|
| encoder_feedback_(Clock::GetRealTimeClock(),
|
| @@ -801,35 +821,44 @@ void VideoSendStreamImpl::SignalEncoderActive() {
|
| max_padding_bitrate_, !config_->suspend_below_min_bitrate);
|
| }
|
|
|
| -void VideoSendStreamImpl::SignalEncoderConfigurationChanged(
|
| - const VideoEncoderConfig& config) {
|
| - RTC_DCHECK_GE(config_->rtp.ssrcs.size(), config.streams.size());
|
| - TRACE_EVENT0("webrtc", "VideoSendStream::SignalEncoderConfigurationChanged");
|
| - LOG(LS_INFO) << "SignalEncoderConfigurationChanged: " << config.ToString();
|
| - RTC_DCHECK_GE(config_->rtp.ssrcs.size(), config.streams.size());
|
| +void VideoSendStreamImpl::OnEncoderConfigurationChanged(
|
| + std::vector<VideoStream> streams,
|
| + int min_transmit_bitrate_bps) {
|
| + if (!worker_queue_->IsCurrent()) {
|
| + // TODO(perkj): Using |this| in post is safe for now since destruction of
|
| + // VideoSendStreamImpl is synchronized in
|
| + // VideoSendStream::StopPermanentlyAndGetRtpStates. But we should really
|
| + // use some kind of weak_ptr to guarantee that VideoSendStreamImpl is still
|
| + // alive when this task runs.
|
| + worker_queue_->PostTask(
|
| + std::unique_ptr<rtc::QueuedTask>(new EncoderReconfiguredTask(
|
| + this, std::move(streams), min_transmit_bitrate_bps)));
|
| + return;
|
| + }
|
| + RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
|
| + TRACE_EVENT0("webrtc", "VideoSendStream::OnEncoderConfigurationChanged");
|
| + RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
|
| RTC_DCHECK_RUN_ON(worker_queue_);
|
|
|
| const int kEncoderMinBitrateBps = 30000;
|
| encoder_min_bitrate_bps_ =
|
| - std::max(config.streams[0].min_bitrate_bps, kEncoderMinBitrateBps);
|
| + std::max(streams[0].min_bitrate_bps, kEncoderMinBitrateBps);
|
| encoder_max_bitrate_bps_ = 0;
|
| - for (const auto& stream : config.streams)
|
| + for (const auto& stream : streams)
|
| encoder_max_bitrate_bps_ += stream.max_bitrate_bps;
|
| - max_padding_bitrate_ =
|
| - CalculateMaxPadBitrateBps(config, config_->suspend_below_min_bitrate);
|
| -
|
| - payload_router_.SetSendStreams(config.streams);
|
| + max_padding_bitrate_ = CalculateMaxPadBitrateBps(
|
| + streams, min_transmit_bitrate_bps, config_->suspend_below_min_bitrate);
|
|
|
| // Clear stats for disabled layers.
|
| - for (size_t i = config.streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
|
| + for (size_t i = streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
|
| stats_proxy_->OnInactiveSsrc(config_->rtp.ssrcs[i]);
|
| }
|
|
|
| size_t number_of_temporal_layers =
|
| - config.streams.back().temporal_layer_thresholds_bps.size() + 1;
|
| + streams.back().temporal_layer_thresholds_bps.size() + 1;
|
| protection_bitrate_calculator_.SetEncodingData(
|
| - config.streams[0].width, config.streams[0].height,
|
| - number_of_temporal_layers, config_->rtp.max_packet_size);
|
| + streams[0].width, streams[0].height, number_of_temporal_layers,
|
| + config_->rtp.max_packet_size);
|
|
|
| if (payload_router_.active()) {
|
| // The send stream is started already. Update the allocator with new bitrate
|
|
|