Chromium Code Reviews| Index: webrtc/video/vie_encoder.cc |
| diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
| index 118959ebecd89a40e42f6f6cd914b52b571b40b4..5a7a9976f1be2498b2ab57a87d257f7ac14506a1 100644 |
| --- a/webrtc/video/vie_encoder.cc |
| +++ b/webrtc/video/vie_encoder.cc |
| @@ -225,6 +225,47 @@ class ViEEncoder::EncodeTask : public rtc::QueuedTask { |
| const int64_t time_when_posted_ms_; |
| }; |
| +// 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. |
|
stefan-webrtc
2016/09/13 09:26:43
"report their"
perkj_webrtc
2016/09/14 14:20:22
encoder reports its Vide,,
|
| +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_); |
| + } |
| + |
| + 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, |
| @@ -233,6 +274,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), |
| @@ -269,23 +311,27 @@ 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); |
| - overuse_detector_.StopCheckForOveruse(); |
| - 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); |
| + overuse_detector_.StopCheckForOveruse(); |
| + 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(&video_sender_); |
| @@ -293,9 +339,15 @@ void ViEEncoder::RegisterProcessThread(ProcessThread* module_process_thread) { |
| } |
| void ViEEncoder::DeRegisterProcessThread() { |
| + RTC_DCHECK_RUN_ON(&main_thread_checker_); |
| 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_); |
| @@ -365,7 +417,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()); |