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

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

Issue 1608743005: Switch to rtc::CriticalSection in IncomingVideoStream and remove one lock. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « webrtc/common_video/include/incoming_video_stream.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
(...skipping 18 matching lines...) Expand all
29 #include "webrtc/system_wrappers/include/tick_util.h" 29 #include "webrtc/system_wrappers/include/tick_util.h"
30 #include "webrtc/system_wrappers/include/trace.h" 30 #include "webrtc/system_wrappers/include/trace.h"
31 #include "webrtc/video_renderer.h" 31 #include "webrtc/video_renderer.h"
32 32
33 namespace webrtc { 33 namespace webrtc {
34 34
35 IncomingVideoStream::IncomingVideoStream(uint32_t stream_id, 35 IncomingVideoStream::IncomingVideoStream(uint32_t stream_id,
36 bool disable_prerenderer_smoothing) 36 bool disable_prerenderer_smoothing)
37 : stream_id_(stream_id), 37 : stream_id_(stream_id),
38 disable_prerenderer_smoothing_(disable_prerenderer_smoothing), 38 disable_prerenderer_smoothing_(disable_prerenderer_smoothing),
39 stream_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
40 thread_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
41 buffer_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
42 incoming_render_thread_(), 39 incoming_render_thread_(),
43 deliver_buffer_event_(EventTimerWrapper::Create()), 40 deliver_buffer_event_(EventTimerWrapper::Create()),
44 running_(false), 41 running_(false),
45 external_callback_(nullptr), 42 external_callback_(nullptr),
46 render_callback_(nullptr), 43 render_callback_(nullptr),
47 render_buffers_(new VideoRenderFrames()), 44 render_buffers_(new VideoRenderFrames()),
48 incoming_rate_(0), 45 incoming_rate_(0),
49 last_rate_calculation_time_ms_(0), 46 last_rate_calculation_time_ms_(0),
50 num_frames_since_last_calculation_(0), 47 num_frames_since_last_calculation_(0),
51 last_render_time_ms_(0), 48 last_render_time_ms_(0),
52 temp_frame_(), 49 temp_frame_(),
53 start_image_(), 50 start_image_(),
54 timeout_image_(), 51 timeout_image_(),
55 timeout_time_() {} 52 timeout_time_() {}
56 53
57 IncomingVideoStream::~IncomingVideoStream() { 54 IncomingVideoStream::~IncomingVideoStream() {
58 Stop(); 55 Stop();
59 } 56 }
60 57
61 VideoRenderCallback* IncomingVideoStream::ModuleCallback() { 58 VideoRenderCallback* IncomingVideoStream::ModuleCallback() {
62 CriticalSectionScoped cs(stream_critsect_.get());
63 return this; 59 return this;
64 } 60 }
65 61
66 int32_t IncomingVideoStream::RenderFrame(const uint32_t stream_id, 62 int32_t IncomingVideoStream::RenderFrame(const uint32_t stream_id,
67 const VideoFrame& video_frame) { 63 const VideoFrame& video_frame) {
68 CriticalSectionScoped csS(stream_critsect_.get()); 64 rtc::CritScope csS(&stream_critsect_);
69 65
70 if (!running_) { 66 if (!running_) {
71 return -1; 67 return -1;
72 } 68 }
73 69
74 // Rate statistics. 70 // Rate statistics.
75 num_frames_since_last_calculation_++; 71 num_frames_since_last_calculation_++;
76 int64_t now_ms = TickTime::MillisecondTimestamp(); 72 int64_t now_ms = TickTime::MillisecondTimestamp();
77 if (now_ms >= last_rate_calculation_time_ms_ + kFrameRatePeriodMs) { 73 if (now_ms >= last_rate_calculation_time_ms_ + kFrameRatePeriodMs) {
78 incoming_rate_ = 74 incoming_rate_ =
79 static_cast<uint32_t>(1000 * num_frames_since_last_calculation_ / 75 static_cast<uint32_t>(1000 * num_frames_since_last_calculation_ /
80 (now_ms - last_rate_calculation_time_ms_)); 76 (now_ms - last_rate_calculation_time_ms_));
81 num_frames_since_last_calculation_ = 0; 77 num_frames_since_last_calculation_ = 0;
82 last_rate_calculation_time_ms_ = now_ms; 78 last_rate_calculation_time_ms_ = now_ms;
83 } 79 }
84 80
85 // Hand over or insert frame. 81 // Hand over or insert frame.
86 if (disable_prerenderer_smoothing_) { 82 if (disable_prerenderer_smoothing_) {
87 DeliverFrame(video_frame); 83 DeliverFrame(video_frame);
88 } else { 84 } else {
89 CriticalSectionScoped csB(buffer_critsect_.get()); 85 rtc::CritScope csB(&buffer_critsect_);
90 if (render_buffers_->AddFrame(video_frame) == 1) { 86 if (render_buffers_->AddFrame(video_frame) == 1) {
91 deliver_buffer_event_->Set(); 87 deliver_buffer_event_->Set();
92 } 88 }
93 } 89 }
94 return 0; 90 return 0;
95 } 91 }
96 92
97 int32_t IncomingVideoStream::SetStartImage(const VideoFrame& video_frame) { 93 int32_t IncomingVideoStream::SetStartImage(const VideoFrame& video_frame) {
98 CriticalSectionScoped csS(thread_critsect_.get()); 94 rtc::CritScope csS(&thread_critsect_);
99 return start_image_.CopyFrame(video_frame); 95 return start_image_.CopyFrame(video_frame);
100 } 96 }
101 97
102 int32_t IncomingVideoStream::SetTimeoutImage(const VideoFrame& video_frame, 98 int32_t IncomingVideoStream::SetTimeoutImage(const VideoFrame& video_frame,
103 const uint32_t timeout) { 99 const uint32_t timeout) {
104 CriticalSectionScoped csS(thread_critsect_.get()); 100 rtc::CritScope csS(&thread_critsect_);
105 timeout_time_ = timeout; 101 timeout_time_ = timeout;
106 return timeout_image_.CopyFrame(video_frame); 102 return timeout_image_.CopyFrame(video_frame);
107 } 103 }
108 104
109 void IncomingVideoStream::SetRenderCallback( 105 void IncomingVideoStream::SetRenderCallback(
110 VideoRenderCallback* render_callback) { 106 VideoRenderCallback* render_callback) {
111 CriticalSectionScoped cs(thread_critsect_.get()); 107 rtc::CritScope cs(&thread_critsect_);
112 render_callback_ = render_callback; 108 render_callback_ = render_callback;
113 } 109 }
114 110
115 int32_t IncomingVideoStream::SetExpectedRenderDelay( 111 int32_t IncomingVideoStream::SetExpectedRenderDelay(
116 int32_t delay_ms) { 112 int32_t delay_ms) {
117 CriticalSectionScoped csS(stream_critsect_.get()); 113 rtc::CritScope csS(&stream_critsect_);
118 if (running_) { 114 if (running_) {
119 return -1; 115 return -1;
120 } 116 }
121 CriticalSectionScoped cs(buffer_critsect_.get()); 117 rtc::CritScope cs(&buffer_critsect_);
122 return render_buffers_->SetRenderDelay(delay_ms); 118 return render_buffers_->SetRenderDelay(delay_ms);
123 } 119 }
124 120
125 void IncomingVideoStream::SetExternalCallback( 121 void IncomingVideoStream::SetExternalCallback(
126 VideoRenderCallback* external_callback) { 122 VideoRenderCallback* external_callback) {
127 CriticalSectionScoped cs(thread_critsect_.get()); 123 rtc::CritScope cs(&thread_critsect_);
128 external_callback_ = external_callback; 124 external_callback_ = external_callback;
129 } 125 }
130 126
131 int32_t IncomingVideoStream::Start() { 127 int32_t IncomingVideoStream::Start() {
132 CriticalSectionScoped csS(stream_critsect_.get()); 128 rtc::CritScope csS(&stream_critsect_);
133 if (running_) { 129 if (running_) {
134 return 0; 130 return 0;
135 } 131 }
136 132
137 if (!disable_prerenderer_smoothing_) { 133 if (!disable_prerenderer_smoothing_) {
138 CriticalSectionScoped csT(thread_critsect_.get()); 134 rtc::CritScope csT(&thread_critsect_);
139 assert(incoming_render_thread_ == NULL); 135 assert(incoming_render_thread_ == NULL);
140 136
141 incoming_render_thread_.reset(new rtc::PlatformThread( 137 incoming_render_thread_.reset(new rtc::PlatformThread(
142 IncomingVideoStreamThreadFun, this, "IncomingVideoStreamThread")); 138 IncomingVideoStreamThreadFun, this, "IncomingVideoStreamThread"));
143 if (!incoming_render_thread_) { 139 if (!incoming_render_thread_) {
144 return -1; 140 return -1;
145 } 141 }
146 142
147 incoming_render_thread_->Start(); 143 incoming_render_thread_->Start();
148 incoming_render_thread_->SetPriority(rtc::kRealtimePriority); 144 incoming_render_thread_->SetPriority(rtc::kRealtimePriority);
149 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs); 145 deliver_buffer_event_->StartTimer(false, kEventStartupTimeMs);
150 } 146 }
151 147
152 running_ = true; 148 running_ = true;
153 return 0; 149 return 0;
154 } 150 }
155 151
156 int32_t IncomingVideoStream::Stop() { 152 int32_t IncomingVideoStream::Stop() {
157 CriticalSectionScoped cs_stream(stream_critsect_.get()); 153 rtc::CritScope cs_stream(&stream_critsect_);
158 154
159 if (!running_) { 155 if (!running_) {
160 return 0; 156 return 0;
161 } 157 }
162 158
163 rtc::PlatformThread* thread = NULL; 159 rtc::PlatformThread* thread = NULL;
164 { 160 {
165 CriticalSectionScoped cs_thread(thread_critsect_.get()); 161 rtc::CritScope cs_thread(&thread_critsect_);
166 if (incoming_render_thread_) { 162 if (incoming_render_thread_) {
167 // Setting the incoming render thread to NULL marks that we're performing 163 // Setting the incoming render thread to NULL marks that we're performing
168 // a shutdown and will make IncomingVideoStreamProcess abort after wakeup. 164 // a shutdown and will make IncomingVideoStreamProcess abort after wakeup.
169 thread = incoming_render_thread_.release(); 165 thread = incoming_render_thread_.release();
170 deliver_buffer_event_->StopTimer(); 166 deliver_buffer_event_->StopTimer();
171 // Set the event to allow the thread to wake up and shut down without 167 // Set the event to allow the thread to wake up and shut down without
172 // waiting for a timeout. 168 // waiting for a timeout.
173 deliver_buffer_event_->Set(); 169 deliver_buffer_event_->Set();
174 } 170 }
175 } 171 }
176 if (thread) { 172 if (thread) {
177 thread->Stop(); 173 thread->Stop();
178 delete thread; 174 delete thread;
179 } 175 }
180 running_ = false; 176 running_ = false;
181 return 0; 177 return 0;
182 } 178 }
183 179
184 int32_t IncomingVideoStream::Reset() { 180 int32_t IncomingVideoStream::Reset() {
185 CriticalSectionScoped cs_buffer(buffer_critsect_.get()); 181 rtc::CritScope cs_buffer(&buffer_critsect_);
186 render_buffers_->ReleaseAllFrames(); 182 render_buffers_->ReleaseAllFrames();
187 return 0; 183 return 0;
188 } 184 }
189 185
190 uint32_t IncomingVideoStream::StreamId() const { 186 uint32_t IncomingVideoStream::StreamId() const {
191 return stream_id_; 187 return stream_id_;
192 } 188 }
193 189
194 uint32_t IncomingVideoStream::IncomingRate() const { 190 uint32_t IncomingVideoStream::IncomingRate() const {
195 CriticalSectionScoped cs(stream_critsect_.get()); 191 rtc::CritScope cs(&stream_critsect_);
196 return incoming_rate_; 192 return incoming_rate_;
197 } 193 }
198 194
199 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) { 195 bool IncomingVideoStream::IncomingVideoStreamThreadFun(void* obj) {
200 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess(); 196 return static_cast<IncomingVideoStream*>(obj)->IncomingVideoStreamProcess();
201 } 197 }
202 198
203 bool IncomingVideoStream::IncomingVideoStreamProcess() { 199 bool IncomingVideoStream::IncomingVideoStreamProcess() {
204 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) { 200 if (kEventError != deliver_buffer_event_->Wait(kEventMaxWaitTimeMs)) {
205 CriticalSectionScoped cs(thread_critsect_.get()); 201 rtc::CritScope cs(&thread_critsect_);
206 if (incoming_render_thread_ == NULL) { 202 if (incoming_render_thread_ == NULL) {
207 // Terminating 203 // Terminating
208 return false; 204 return false;
209 } 205 }
210 206
211 // Get a new frame to render and the time for the frame after this one. 207 // Get a new frame to render and the time for the frame after this one.
212 VideoFrame frame_to_render; 208 VideoFrame frame_to_render;
213 uint32_t wait_time; 209 uint32_t wait_time;
214 { 210 {
215 CriticalSectionScoped cs(buffer_critsect_.get()); 211 rtc::CritScope cs(&buffer_critsect_);
216 frame_to_render = render_buffers_->FrameToRender(); 212 frame_to_render = render_buffers_->FrameToRender();
217 wait_time = render_buffers_->TimeToNextFrameRelease(); 213 wait_time = render_buffers_->TimeToNextFrameRelease();
218 } 214 }
219 215
220 // Set timer for next frame to render. 216 // Set timer for next frame to render.
221 if (wait_time > kEventMaxWaitTimeMs) { 217 if (wait_time > kEventMaxWaitTimeMs) {
222 wait_time = kEventMaxWaitTimeMs; 218 wait_time = kEventMaxWaitTimeMs;
223 } 219 }
224 deliver_buffer_event_->StartTimer(false, wait_time); 220 deliver_buffer_event_->StartTimer(false, wait_time);
225 221
226 DeliverFrame(frame_to_render); 222 DeliverFrame(frame_to_render);
227 } 223 }
228 return true; 224 return true;
229 } 225 }
230 226
231 void IncomingVideoStream::DeliverFrame(const VideoFrame& video_frame) { 227 void IncomingVideoStream::DeliverFrame(const VideoFrame& video_frame) {
232 CriticalSectionScoped cs(thread_critsect_.get()); 228 rtc::CritScope cs(&thread_critsect_);
233 if (video_frame.IsZeroSize()) { 229 if (video_frame.IsZeroSize()) {
234 if (render_callback_) { 230 if (render_callback_) {
235 if (last_render_time_ms_ == 0 && !start_image_.IsZeroSize()) { 231 if (last_render_time_ms_ == 0 && !start_image_.IsZeroSize()) {
236 // We have not rendered anything and have a start image. 232 // We have not rendered anything and have a start image.
237 temp_frame_.CopyFrame(start_image_); 233 temp_frame_.CopyFrame(start_image_);
238 render_callback_->RenderFrame(stream_id_, temp_frame_); 234 render_callback_->RenderFrame(stream_id_, temp_frame_);
239 } else if (!timeout_image_.IsZeroSize() && 235 } else if (!timeout_image_.IsZeroSize() &&
240 last_render_time_ms_ + timeout_time_ < 236 last_render_time_ms_ + timeout_time_ <
241 TickTime::MillisecondTimestamp()) { 237 TickTime::MillisecondTimestamp()) {
242 // Render a timeout image. 238 // Render a timeout image.
(...skipping 11 matching lines...) Expand all
254 external_callback_->RenderFrame(stream_id_, video_frame); 250 external_callback_->RenderFrame(stream_id_, video_frame);
255 } else if (render_callback_) { 251 } else if (render_callback_) {
256 render_callback_->RenderFrame(stream_id_, video_frame); 252 render_callback_->RenderFrame(stream_id_, video_frame);
257 } 253 }
258 254
259 // We're done with this frame. 255 // We're done with this frame.
260 last_render_time_ms_ = video_frame.render_time_ms(); 256 last_render_time_ms_ = video_frame.render_time_ms();
261 } 257 }
262 258
263 } // namespace webrtc 259 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/include/incoming_video_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698