Chromium Code Reviews| Index: webrtc/video/vie_encoder.cc |
| diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
| index f6545431291b517235dfcc77c0e3261e44fa7d3d..0cf27947095767bbf2f1710f0559dc3760bcdf03 100644 |
| --- a/webrtc/video/vie_encoder.cc |
| +++ b/webrtc/video/vie_encoder.cc |
| @@ -221,6 +221,46 @@ class ViEEncoder::EncodeTask : public rtc::QueuedTask { |
| ViEEncoder* vie_encoder_; |
| }; |
| +// VideoSourceProxy is responsible ensuring thread safety between calls to |
| +// ViEEncoder::SetSource that will happen on libjingles worker thread when a |
| +// video capturer is connected to the encoder and the encoder task queue |
| +// (encoder_queue_) where encoders report its VideoSinkWants. |
| +class ViEEncoder::VideoSourceProxy { |
| + public: |
| + explicit VideoSourceProxy(ViEEncoder* vie_encoder) |
| + : vie_encoder_(vie_encoder), source_(nullptr) {} |
| + |
| + void SetSource(rtc::VideoSourceInterface<VideoFrame>* source) { |
| + RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); |
| + rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; |
| + { |
| + rtc::CritScope lock(&crit_); |
| + old_source = source_; |
| + source_ = source; |
| + } |
| + |
| + if (old_source != source && old_source != nullptr) { |
| + old_source->RemoveSink(vie_encoder_); |
| + } |
|
sprang_webrtc
2016/09/06 10:04:57
nit: remove {} here or add them below, just so we'
perkj_webrtc
2016/09/07 15:10:37
Done.
|
| + |
| + if (!source) |
| + return; |
| + |
| + // TODO(perkj): Let VideoSourceProxy implement LoadObserver and truly send |
| + // CPU load as sink wants. |
| + rtc::VideoSinkWants wants; |
| + source->AddOrUpdateSink(vie_encoder_, wants); |
| + } |
| + |
| + private: |
| + rtc::CriticalSection crit_; |
| + rtc::SequencedTaskChecker main_checker_; |
| + ViEEncoder* vie_encoder_; |
| + rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); |
| + |
| + RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); |
| +}; |
| + |
| ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
| SendStatisticsProxy* stats_proxy, |
| const VideoSendStream::Config::EncoderSettings& settings, |
| @@ -229,6 +269,7 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
| EncodedFrameObserver* encoder_timing) |
| : shutdown_event_(true /* manual_reset */, false), |
| number_of_cores_(number_of_cores), |
| + source_proxy_(new VideoSourceProxy(this)), |
| settings_(settings), |
| vp_(VideoProcessing::Create()), |
| video_sender_(Clock::GetRealTimeClock(), this, this), |
| @@ -264,22 +305,26 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
| } |
| ViEEncoder::~ViEEncoder() { |
| + RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| RTC_DCHECK(shutdown_event_.Wait(0)) |
| << "Must call ::Stop() before destruction."; |
| } |
| void ViEEncoder::Stop() { |
| - if (!encoder_queue_.IsCurrent()) { |
| - encoder_queue_.PostTask([this] { Stop(); }); |
| - shutdown_event_.Wait(rtc::Event::kForever); |
| - return; |
| - } |
| - RTC_DCHECK_RUN_ON(&encoder_queue_); |
| - video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, false); |
| - shutdown_event_.Set(); |
| + RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| + source_proxy_->SetSource(nullptr); |
| + encoder_queue_.PostTask([this] { |
| + RTC_DCHECK_RUN_ON(&encoder_queue_); |
| + video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, |
| + false); |
| + shutdown_event_.Set(); |
| + }); |
| + |
| + shutdown_event_.Wait(rtc::Event::kForever); |
| } |
| void ViEEncoder::RegisterProcessThread(ProcessThread* module_process_thread) { |
| + RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| RTC_DCHECK(!module_process_thread_); |
| module_process_thread_ = module_process_thread; |
| module_process_thread_->RegisterModule(&overuse_detector_); |
| @@ -288,10 +333,16 @@ void ViEEncoder::RegisterProcessThread(ProcessThread* module_process_thread) { |
| } |
| void ViEEncoder::DeRegisterProcessThread() { |
| + RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| module_process_thread_->DeRegisterModule(&overuse_detector_); |
| module_process_thread_->DeRegisterModule(&video_sender_); |
| } |
| +void ViEEncoder::SetSource(rtc::VideoSourceInterface<VideoFrame>* source) { |
| + RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| + source_proxy_->SetSource(source); |
| +} |
| + |
| void ViEEncoder::SetSink(EncodedImageCallback* sink) { |
| encoder_queue_.PostTask([this, sink] { |
| RTC_DCHECK_RUN_ON(&encoder_queue_); |
| @@ -361,7 +412,7 @@ void ViEEncoder::ConfigureEncoderInternal(const VideoCodec& video_codec, |
| } |
| } |
| -void ViEEncoder::IncomingCapturedFrame(const VideoFrame& video_frame) { |
| +void ViEEncoder::OnFrame(const VideoFrame& video_frame) { |
| RTC_DCHECK_RUNS_SERIALIZED(&incoming_frame_race_checker_); |
| stats_proxy_->OnIncomingFrame(video_frame.width(), video_frame.height()); |