Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1322)

Side by Side Diff: webrtc/common_video/incoming_video_stream.cc

Issue 2071473002: Reland of Split IncomingVideoStream into two implementations, with smoothing and without. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: add explicit Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/common_video/include/incoming_video_stream.h" 11 #include "webrtc/common_video/include/incoming_video_stream.h"
12 12
13 #include <assert.h> 13 #include "webrtc/base/atomicops.h"
14
15 #include "webrtc/base/platform_thread.h" 14 #include "webrtc/base/platform_thread.h"
16 #include "webrtc/base/timeutils.h" 15 #include "webrtc/base/timeutils.h"
17 #include "webrtc/common_video/video_render_frames.h" 16 #include "webrtc/common_video/video_render_frames.h"
18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/include/event_wrapper.h" 18 #include "webrtc/system_wrappers/include/event_wrapper.h"
20 19
21 namespace webrtc { 20 namespace webrtc {
22 21
23 IncomingVideoStream::IncomingVideoStream(bool disable_prerenderer_smoothing) 22 IncomingVideoStream::IncomingVideoStream(
24 : disable_prerenderer_smoothing_(disable_prerenderer_smoothing), 23 int32_t delay_ms,
25 incoming_render_thread_(), 24 rtc::VideoSinkInterface<VideoFrame>* callback)
25 : incoming_render_thread_(&IncomingVideoStreamThreadFun,
26 this,
27 "IncomingVideoStreamThread"),
26 deliver_buffer_event_(EventTimerWrapper::Create()), 28 deliver_buffer_event_(EventTimerWrapper::Create()),
27 running_(false), 29 external_callback_(callback),
28 external_callback_(nullptr), 30 render_buffers_(new VideoRenderFrames(delay_ms)) {
29 render_buffers_(new VideoRenderFrames()) {} 31 RTC_DCHECK(external_callback_);
32
33 render_thread_checker_.DetachFromThread();
34 decoder_thread_checker_.DetachFromThread();
35
36 incoming_render_thread_.Start();
37 incoming_render_thread_.SetPriority(rtc::kRealtimePriority);
38 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
39 }
30 40
31 IncomingVideoStream::~IncomingVideoStream() { 41 IncomingVideoStream::~IncomingVideoStream() {
32 Stop(); 42 RTC_DCHECK(main_thread_checker_.CalledOnValidThread());
43
44 {
45 rtc::CritScope cs(&buffer_critsect_);
46 render_buffers_.reset();
47 }
48
49 deliver_buffer_event_->Set();
50 incoming_render_thread_.Stop();
51 deliver_buffer_event_->StopTimer();
33 } 52 }
34 53
35 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) { 54 void IncomingVideoStream::OnFrame(const VideoFrame& video_frame) {
36 rtc::CritScope csS(&stream_critsect_); 55 RTC_DCHECK_RUN_ON(&decoder_thread_checker_);
37
38 if (!running_) {
39 return;
40 }
41 56
42 // Hand over or insert frame. 57 // Hand over or insert frame.
43 if (disable_prerenderer_smoothing_) { 58 rtc::CritScope csB(&buffer_critsect_);
44 DeliverFrame(video_frame); 59 if (render_buffers_->AddFrame(video_frame) == 1) {
45 } else { 60 deliver_buffer_event_->Set();
46 rtc::CritScope csB(&buffer_critsect_);
47 if (render_buffers_->AddFrame(video_frame) == 1) {
48 deliver_buffer_event_->Set();
49 }
50 } 61 }
51 } 62 }
52 63
53 int32_t IncomingVideoStream::SetExpectedRenderDelay(
54 int32_t delay_ms) {
55 rtc::CritScope csS(&stream_critsect_);
56 if (running_) {
57 return -1;
58 }
59 rtc::CritScope cs(&buffer_critsect_);
60 return render_buffers_->SetRenderDelay(delay_ms);
61 }
62
63 void IncomingVideoStream::SetExternalCallback(
64 rtc::VideoSinkInterface<VideoFrame>* external_callback) {
65 rtc::CritScope cs(&thread_critsect_);
66 external_callback_ = external_callback;
67 }
68
69 int32_t IncomingVideoStream::Start() {
70 rtc::CritScope csS(&stream_critsect_);
71 if (running_) {
72 return 0;
73 }
74
75 if (!disable_prerenderer_smoothing_) {
76 rtc::CritScope csT(&thread_critsect_);
77 assert(incoming_render_thread_ == NULL);
78
79 incoming_render_thread_.reset(new rtc::PlatformThread(
80 IncomingVideoStreamThreadFun, this, "IncomingVideoStreamThread"));
81 if (!incoming_render_thread_) {
82 return -1;
83 }
84
85 incoming_render_thread_->Start();
86 incoming_render_thread_->SetPriority(rtc::kRealtimePriority);
87 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
88 }
89
90 running_ = true;
91 return 0;
92 }
93
94 int32_t IncomingVideoStream::Stop() {
95 rtc::CritScope cs_stream(&stream_critsect_);
96
97 if (!running_) {
98 return 0;
99 }
100
101 rtc::PlatformThread* thread = NULL;
102 {
103 rtc::CritScope cs_thread(&thread_critsect_);
104 if (incoming_render_thread_) {
105 // Setting the incoming render thread to NULL marks that we're performing
106 // a shutdown and will make IncomingVideoStreamProcess abort after wakeup.
107 thread = incoming_render_thread_.release();
108 deliver_buffer_event_->StopTimer();
109 // Set the event to allow the thread to wake up and shut down without
110 // waiting for a timeout.
111 deliver_buffer_event_->Set();
112 }
113 }
114 if (thread) {
115 thread->Stop();
116 delete thread;
117 }
118 running_ = false;
119 return 0;
120 }
121
122 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { 64 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) {
123 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess(); 65 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess();
124 } 66 }
125 67
126 bool IncomingVideoStream::IncomingVideoStreamProcess() { 68 bool IncomingVideoStream::IncomingVideoStreamProcess() {
69 RTC_DCHECK_RUN_ON(&render_thread_checker_);
70
127 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { 71 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) {
128 rtc::CritScope cs(&thread_critsect_);
129 if (incoming_render_thread_ == NULL) {
130 // Terminating
131 return false;
132 }
133
134 // Get a new frame to render and the time for the frame after this one. 72 // Get a new frame to render and the time for the frame after this one.
135 rtc::Optional<VideoFrame> frame_to_render; 73 rtc::Optional<VideoFrame> frame_to_render;
136 uint32_t wait_time; 74 uint32_t wait_time;
137 { 75 {
138 rtc::CritScope cs(&buffer_critsect_); 76 rtc::CritScope cs(&buffer_critsect_);
77 if (!render_buffers_.get()) {
78 // Terminating
79 return false;
80 }
139 frame_to_render = render_buffers_->FrameToRender(); 81 frame_to_render = render_buffers_->FrameToRender();
140 wait_time = render_buffers_->TimeToNextFrameRelease(); 82 wait_time = render_buffers_->TimeToNextFrameRelease();
141 } 83 }
142 84
143 // Set timer for next frame to render. 85 // Set timer for next frame to render.
144 if (wait_time > kEventMaxWaitTimeMs) { 86 if (wait_time > kEventMaxWaitTimeMs) {
145 wait_time = kEventMaxWaitTimeMs; 87 wait_time = kEventMaxWaitTimeMs;
146 } 88 }
89
147 deliver_buffer_event_->StartTimer(false, wait_time); 90 deliver_buffer_event_->StartTimer(false, wait_time);
148 91
149 if (frame_to_render) 92 if (frame_to_render) {
150 DeliverFrame(*frame_to_render); 93 external_callback_->OnFrame(*frame_to_render);
94 }
151 } 95 }
152 return true; 96 return true;
153 } 97 }
154 98
155 void IncomingVideoStream::DeliverFrame(const VideoFrame& video_frame) { 99 ////////////////////////////////////////////////////////////////////////////////
156 rtc::CritScope cs(&thread_critsect_); 100 IncomingVideoStreamNoSmoothing::IncomingVideoStreamNoSmoothing(
101 rtc::VideoSinkInterface<VideoFrame>* callback)
102 : callback_(callback), queue_("InVideoStream") {
103 decoder_thread_checker_.DetachFromThread();
104 }
157 105
158 // Send frame for rendering. 106 void IncomingVideoStreamNoSmoothing::OnFrame(const VideoFrame& video_frame) {
159 if (external_callback_) { 107 RTC_DCHECK_RUN_ON(&decoder_thread_checker_);
160 external_callback_->OnFrame(video_frame); 108 queue_.PostTask([video_frame, this]() { callback_->OnFrame(video_frame); });
161 }
162 } 109 }
163 110
164 } // namespace webrtc 111 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/include/incoming_video_stream.h ('k') | webrtc/common_video/incoming_video_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698