Chromium Code Reviews| Index: webrtc/common_video/incoming_video_stream.cc |
| diff --git a/webrtc/common_video/incoming_video_stream.cc b/webrtc/common_video/incoming_video_stream.cc |
| index a5e7ba755d35023ad9ba063d37b0e6b928305077..a95be61de99c9c3e23df4483294ce146d41d6178 100644 |
| --- a/webrtc/common_video/incoming_video_stream.cc |
| +++ b/webrtc/common_video/incoming_video_stream.cc |
| @@ -10,8 +10,7 @@ |
| #include "webrtc/common_video/include/incoming_video_stream.h" |
| -#include <assert.h> |
| - |
| +#include "webrtc/base/atomicops.h" |
| #include "webrtc/base/platform_thread.h" |
| #include "webrtc/base/timeutils.h" |
| #include "webrtc/common_video/video_render_frames.h" |
| @@ -20,103 +19,46 @@ |
| namespace webrtc { |
| -IncomingVideoStream::IncomingVideoStream(bool disable_prerenderer_smoothing) |
| - : disable_prerenderer_smoothing_(disable_prerenderer_smoothing), |
| - incoming_render_thread_(), |
| +IncomingVideoStream::IncomingVideoStream( |
| + int32_t delay_ms, |
| + rtc::VideoSinkInterface<VideoFrame>* callback) |
| + : incoming_render_thread_(&IncomingVideoStreamThreadFun, |
| + this, |
| + "IncomingVideoStreamThread"), |
| deliver_buffer_event_(EventTimerWrapper::Create()), |
| - running_(false), |
| - external_callback_(nullptr), |
| - render_buffers_(new VideoRenderFrames()) {} |
| - |
| -IncomingVideoStream::~IncomingVideoStream() { |
| - Stop(); |
| -} |
| - |
| -void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { |
| - rtc::CritScope csS(&stream_critsect_); |
| - |
| - if (!running_) { |
| - return; |
| - } |
| - |
| - // Hand over or insert frame. |
| - if (disable_prerenderer_smoothing_) { |
| - DeliverFrame(video_frame); |
| - } else { |
| - rtc::CritScope csB(&buffer_critsect_); |
| - if (render_buffers_->AddFrame(video_frame) == 1) { |
| - deliver_buffer_event_->Set(); |
| - } |
| - } |
| -} |
| + external_callback_(callback), |
| + render_buffers_(new VideoRenderFrames(delay_ms)) { |
| + RTC_DCHECK(external_callback_); |
| -int32_t IncomingVideoStream::SetExpectedRenderDelay( |
| - int32_t delay_ms) { |
| - rtc::CritScope csS(&stream_critsect_); |
| - if (running_) { |
| - return -1; |
| - } |
| - rtc::CritScope cs(&buffer_critsect_); |
| - return render_buffers_->SetRenderDelay(delay_ms); |
| -} |
| + render_thread_checker_.DetachFromThread(); |
| + decoder_thread_checker_.DetachFromThread(); |
| -void IncomingVideoStream::SetExternalCallback( |
| - rtc::VideoSinkInterface<VideoFrame>* external_callback) { |
| - rtc::CritScope cs(&thread_critsect_); |
| - external_callback_ = external_callback; |
| + incoming_render_thread_.Start(); |
| + incoming_render_thread_.SetPriority(rtc::kRealtimePriority); |
| + deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs); |
| } |
| -int32_t IncomingVideoStream::Start() { |
| - rtc::CritScope csS(&stream_critsect_); |
| - if (running_) { |
| - return 0; |
| - } |
| - |
| - if (!disable_prerenderer_smoothing_) { |
| - rtc::CritScope csT(&thread_critsect_); |
| - assert(incoming_render_thread_ == NULL); |
| - |
| - incoming_render_thread_.reset(new rtc::PlatformThread( |
| - IncomingVideoStreamThreadFun, this, "IncomingVideoStreamThread")); |
| - if (!incoming_render_thread_) { |
| - return -1; |
| - } |
| +IncomingVideoStream::~IncomingVideoStream() { |
| + RTC_DCHECK(main_thread_checker_.CalledOnValidThread()); |
| - incoming_render_thread_->Start(); |
| - incoming_render_thread_->SetPriority(rtc::kRealtimePriority); |
| - deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs); |
| + { |
| + rtc::CritScope cs(&buffer_critsect_); |
| + render_buffers_.reset(); |
| } |
| - running_ = true; |
| - return 0; |
| + deliver_buffer_event_->Set(); |
| + incoming_render_thread_.Stop(); |
| + deliver_buffer_event_->StopTimer(); |
| } |
| -int32_t IncomingVideoStream::Stop() { |
| - rtc::CritScope cs_stream(&stream_critsect_); |
| - |
| - if (!running_) { |
| - return 0; |
| - } |
| +void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { |
| + RTC_DCHECK_RUN_ON(&decoder_thread_checker_); |
| - rtc::PlatformThread* thread = NULL; |
| - { |
| - rtc::CritScope cs_thread(&thread_critsect_); |
| - if (incoming_render_thread_) { |
| - // Setting the incoming render thread to NULL marks that we're performing |
| - // a shutdown and will make IncomingVideoStreamProcess abort after wakeup. |
| - thread = incoming_render_thread_.release(); |
| - deliver_buffer_event_->StopTimer(); |
| - // Set the event to allow the thread to wake up and shut down without |
| - // waiting for a timeout. |
| - deliver_buffer_event_->Set(); |
| - } |
| - } |
| - if (thread) { |
| - thread->Stop(); |
| - delete thread; |
| + // Hand over or insert frame. |
| + rtc::CritScope csB(&buffer_critsect_); |
| + if (render_buffers_->AddFrame(video_frame) == 1) { |
| + deliver_buffer_event_->Set(); |
| } |
| - running_ = false; |
| - return 0; |
| } |
| bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { |
| @@ -124,18 +66,18 @@ bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { |
| } |
| bool IncomingVideoStream::IncomingVideoStreamProcess() { |
| - if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { |
| - rtc::CritScope cs(&thread_critsect_); |
| - if (incoming_render_thread_ == NULL) { |
| - // Terminating |
| - return false; |
| - } |
| + RTC_DCHECK_RUN_ON(&render_thread_checker_); |
| + if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { |
| // Get a new frame to render and the time for the frame after this one. |
| rtc::Optional<VideoFrame> frame_to_render; |
| uint32_t wait_time; |
| { |
| rtc::CritScope cs(&buffer_critsect_); |
| + if (!render_buffers_.get()) { |
| + // Terminating |
| + return false; |
| + } |
| frame_to_render = render_buffers_->FrameToRender(); |
| wait_time = render_buffers_->TimeToNextFrameRelease(); |
| } |
| @@ -144,21 +86,28 @@ bool IncomingVideoStream::IncomingVideoStreamProcess() { |
| if (wait_time > kEventMaxWaitTimeMs) { |
| wait_time = kEventMaxWaitTimeMs; |
| } |
| + |
| deliver_buffer_event_->StartTimer(false, wait_time); |
| - if (frame_to_render) |
| - DeliverFrame(*frame_to_render); |
| + if (frame_to_render) { |
| + external_callback_->OnFrame(*frame_to_render); |
| + } |
| } |
| return true; |
| } |
| -void IncomingVideoStream::DeliverFrame(const VideoFrame& video_frame) { |
| - rtc::CritScope cs(&thread_critsect_); |
| - |
| - // Send frame for rendering. |
| - if (external_callback_) { |
| - external_callback_->OnFrame(video_frame); |
| - } |
| +//////////////////////////////////////////////////////////////////////////////// |
| +IncomingVideoStreamNoSmoothing::IncomingVideoStreamNoSmoothing( |
| + rtc::VideoSinkInterface<VideoFrame>* callback) |
| + : callback_(callback), queue_("InVideoStream") {} |
| + |
| +void IncomingVideoStreamNoSmoothing::OnFrame(const VideoFrame& video_frame) { |
| + rtc::AtomicOps::Increment(&queued_frames_); |
|
mflodman
2016/06/13 18:39:24
Can you add a thread check here?
RTC_DCHECK_RUN_O
tommi
2016/06/14 08:11:27
Done.
|
| + queue_.PostTask([video_frame, this]() { |
| + int pending = rtc::AtomicOps::Decrement(&queued_frames_); |
| + if (pending < kMaxQueuedFrames) |
| + callback_->OnFrame(video_frame); |
| + }); |
| } |
| } // namespace webrtc |