OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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/modules/video_coding/frame_buffer2.h" | 11 #include "webrtc/modules/video_coding/frame_buffer2.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <cstring> | 14 #include <cstring> |
15 #include <queue> | 15 #include <queue> |
16 | 16 |
17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
| 19 #include "webrtc/base/trace_event.h" |
19 #include "webrtc/modules/video_coding/include/video_coding_defines.h" | 20 #include "webrtc/modules/video_coding/include/video_coding_defines.h" |
20 #include "webrtc/modules/video_coding/jitter_estimator.h" | 21 #include "webrtc/modules/video_coding/jitter_estimator.h" |
21 #include "webrtc/modules/video_coding/timing.h" | 22 #include "webrtc/modules/video_coding/timing.h" |
22 #include "webrtc/system_wrappers/include/clock.h" | 23 #include "webrtc/system_wrappers/include/clock.h" |
23 #include "webrtc/system_wrappers/include/metrics.h" | 24 #include "webrtc/system_wrappers/include/metrics.h" |
24 | 25 |
25 namespace webrtc { | 26 namespace webrtc { |
26 namespace video_coding { | 27 namespace video_coding { |
27 | 28 |
28 namespace { | 29 namespace { |
(...skipping 19 matching lines...) Expand all Loading... |
48 num_frames_buffered_(0), | 49 num_frames_buffered_(0), |
49 stopped_(false), | 50 stopped_(false), |
50 protection_mode_(kProtectionNack), | 51 protection_mode_(kProtectionNack), |
51 stats_callback_(stats_callback) {} | 52 stats_callback_(stats_callback) {} |
52 | 53 |
53 FrameBuffer::~FrameBuffer() {} | 54 FrameBuffer::~FrameBuffer() {} |
54 | 55 |
55 FrameBuffer::ReturnReason FrameBuffer::NextFrame( | 56 FrameBuffer::ReturnReason FrameBuffer::NextFrame( |
56 int64_t max_wait_time_ms, | 57 int64_t max_wait_time_ms, |
57 std::unique_ptr<FrameObject>* frame_out) { | 58 std::unique_ptr<FrameObject>* frame_out) { |
| 59 TRACE_EVENT0("webrtc", "FrameBuffer::NextFrame"); |
58 int64_t latest_return_time_ms = | 60 int64_t latest_return_time_ms = |
59 clock_->TimeInMilliseconds() + max_wait_time_ms; | 61 clock_->TimeInMilliseconds() + max_wait_time_ms; |
60 int64_t wait_ms = max_wait_time_ms; | 62 int64_t wait_ms = max_wait_time_ms; |
61 | 63 |
62 do { | 64 do { |
63 int64_t now_ms = clock_->TimeInMilliseconds(); | 65 int64_t now_ms = clock_->TimeInMilliseconds(); |
64 { | 66 { |
65 rtc::CritScope lock(&crit_); | 67 rtc::CritScope lock(&crit_); |
66 new_countinuous_frame_event_.Reset(); | 68 new_countinuous_frame_event_.Reset(); |
67 if (stopped_) | 69 if (stopped_) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 // means that the frame buffer was cleared as the thread in this function | 149 // means that the frame buffer was cleared as the thread in this function |
148 // was waiting to acquire |crit_| in order to return. Wait for the | 150 // was waiting to acquire |crit_| in order to return. Wait for the |
149 // remaining time and then return. | 151 // remaining time and then return. |
150 return NextFrame(latest_return_time_ms - now_ms, frame_out); | 152 return NextFrame(latest_return_time_ms - now_ms, frame_out); |
151 } else { | 153 } else { |
152 return kTimeout; | 154 return kTimeout; |
153 } | 155 } |
154 } | 156 } |
155 | 157 |
156 void FrameBuffer::SetProtectionMode(VCMVideoProtection mode) { | 158 void FrameBuffer::SetProtectionMode(VCMVideoProtection mode) { |
| 159 TRACE_EVENT0("webrtc", "FrameBuffer::SetProtectionMode"); |
157 rtc::CritScope lock(&crit_); | 160 rtc::CritScope lock(&crit_); |
158 protection_mode_ = mode; | 161 protection_mode_ = mode; |
159 } | 162 } |
160 | 163 |
161 void FrameBuffer::Start() { | 164 void FrameBuffer::Start() { |
| 165 TRACE_EVENT0("webrtc", "FrameBuffer::Start"); |
162 rtc::CritScope lock(&crit_); | 166 rtc::CritScope lock(&crit_); |
163 stopped_ = false; | 167 stopped_ = false; |
164 } | 168 } |
165 | 169 |
166 void FrameBuffer::Stop() { | 170 void FrameBuffer::Stop() { |
| 171 TRACE_EVENT0("webrtc", "FrameBuffer::Stop"); |
167 rtc::CritScope lock(&crit_); | 172 rtc::CritScope lock(&crit_); |
168 stopped_ = true; | 173 stopped_ = true; |
169 new_countinuous_frame_event_.Set(); | 174 new_countinuous_frame_event_.Set(); |
170 } | 175 } |
171 | 176 |
172 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { | 177 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { |
| 178 TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame"); |
173 rtc::CritScope lock(&crit_); | 179 rtc::CritScope lock(&crit_); |
174 RTC_DCHECK(frame); | 180 RTC_DCHECK(frame); |
175 | 181 |
176 if (stats_callback_) | 182 if (stats_callback_) |
177 stats_callback_->OnCompleteFrame(frame->num_references == 0, frame->size()); | 183 stats_callback_->OnCompleteFrame(frame->num_references == 0, frame->size()); |
178 | 184 |
179 FrameKey key(frame->picture_id, frame->spatial_layer); | 185 FrameKey key(frame->picture_id, frame->spatial_layer); |
180 int last_continuous_picture_id = | 186 int last_continuous_picture_id = |
181 last_continuous_frame_it_ == frames_.end() | 187 last_continuous_frame_it_ == frames_.end() |
182 ? -1 | 188 ? -1 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 // Since we now have new continuous frames there might be a better frame | 251 // Since we now have new continuous frames there might be a better frame |
246 // to return from NextFrame. Signal that thread so that it again can choose | 252 // to return from NextFrame. Signal that thread so that it again can choose |
247 // which frame to return. | 253 // which frame to return. |
248 new_countinuous_frame_event_.Set(); | 254 new_countinuous_frame_event_.Set(); |
249 } | 255 } |
250 | 256 |
251 return last_continuous_picture_id; | 257 return last_continuous_picture_id; |
252 } | 258 } |
253 | 259 |
254 void FrameBuffer::PropagateContinuity(FrameMap::iterator start) { | 260 void FrameBuffer::PropagateContinuity(FrameMap::iterator start) { |
| 261 TRACE_EVENT0("webrtc", "FrameBuffer::PropagateContinuity"); |
255 RTC_DCHECK(start->second.continuous); | 262 RTC_DCHECK(start->second.continuous); |
256 if (last_continuous_frame_it_ == frames_.end()) | 263 if (last_continuous_frame_it_ == frames_.end()) |
257 last_continuous_frame_it_ = start; | 264 last_continuous_frame_it_ = start; |
258 | 265 |
259 std::queue<FrameMap::iterator> continuous_frames; | 266 std::queue<FrameMap::iterator> continuous_frames; |
260 continuous_frames.push(start); | 267 continuous_frames.push(start); |
261 | 268 |
262 // A simple BFS to traverse continuous frames. | 269 // A simple BFS to traverse continuous frames. |
263 while (!continuous_frames.empty()) { | 270 while (!continuous_frames.empty()) { |
264 auto frame = continuous_frames.front(); | 271 auto frame = continuous_frames.front(); |
(...skipping 10 matching lines...) Expand all Loading... |
275 | 282 |
276 if (frame_ref->second.num_missing_continuous == 0) { | 283 if (frame_ref->second.num_missing_continuous == 0) { |
277 frame_ref->second.continuous = true; | 284 frame_ref->second.continuous = true; |
278 continuous_frames.push(frame_ref); | 285 continuous_frames.push(frame_ref); |
279 } | 286 } |
280 } | 287 } |
281 } | 288 } |
282 } | 289 } |
283 | 290 |
284 void FrameBuffer::PropagateDecodability(const FrameInfo& info) { | 291 void FrameBuffer::PropagateDecodability(const FrameInfo& info) { |
| 292 TRACE_EVENT0("webrtc", "FrameBuffer::PropagateDecodability"); |
285 for (size_t d = 0; d < info.num_dependent_frames; ++d) { | 293 for (size_t d = 0; d < info.num_dependent_frames; ++d) { |
286 auto ref_info = frames_.find(info.dependent_frames[d]); | 294 auto ref_info = frames_.find(info.dependent_frames[d]); |
287 RTC_DCHECK(ref_info != frames_.end()); | 295 RTC_DCHECK(ref_info != frames_.end()); |
288 RTC_DCHECK_GT(ref_info->second.num_missing_decodable, 0U); | 296 RTC_DCHECK_GT(ref_info->second.num_missing_decodable, 0U); |
289 --ref_info->second.num_missing_decodable; | 297 --ref_info->second.num_missing_decodable; |
290 } | 298 } |
291 } | 299 } |
292 | 300 |
293 void FrameBuffer::AdvanceLastDecodedFrame(FrameMap::iterator decoded) { | 301 void FrameBuffer::AdvanceLastDecodedFrame(FrameMap::iterator decoded) { |
| 302 TRACE_EVENT0("webrtc", "FrameBuffer::AdvanceLastDecodedFrame"); |
294 if (last_decoded_frame_it_ == frames_.end()) { | 303 if (last_decoded_frame_it_ == frames_.end()) { |
295 last_decoded_frame_it_ = frames_.begin(); | 304 last_decoded_frame_it_ = frames_.begin(); |
296 } else { | 305 } else { |
297 RTC_DCHECK(last_decoded_frame_it_->first < decoded->first); | 306 RTC_DCHECK(last_decoded_frame_it_->first < decoded->first); |
298 ++last_decoded_frame_it_; | 307 ++last_decoded_frame_it_; |
299 } | 308 } |
300 --num_frames_buffered_; | 309 --num_frames_buffered_; |
301 ++num_frames_history_; | 310 ++num_frames_history_; |
302 | 311 |
303 // First, delete non-decoded frames from the history. | 312 // First, delete non-decoded frames from the history. |
304 while (last_decoded_frame_it_ != decoded) { | 313 while (last_decoded_frame_it_ != decoded) { |
305 if (last_decoded_frame_it_->second.frame) | 314 if (last_decoded_frame_it_->second.frame) |
306 --num_frames_buffered_; | 315 --num_frames_buffered_; |
307 last_decoded_frame_it_ = frames_.erase(last_decoded_frame_it_); | 316 last_decoded_frame_it_ = frames_.erase(last_decoded_frame_it_); |
308 } | 317 } |
309 | 318 |
310 // Then remove old history if we have too much history saved. | 319 // Then remove old history if we have too much history saved. |
311 if (num_frames_history_ > kMaxFramesHistory) { | 320 if (num_frames_history_ > kMaxFramesHistory) { |
312 frames_.erase(frames_.begin()); | 321 frames_.erase(frames_.begin()); |
313 --num_frames_history_; | 322 --num_frames_history_; |
314 } | 323 } |
315 } | 324 } |
316 | 325 |
317 bool FrameBuffer::UpdateFrameInfoWithIncomingFrame(const FrameObject& frame, | 326 bool FrameBuffer::UpdateFrameInfoWithIncomingFrame(const FrameObject& frame, |
318 FrameMap::iterator info) { | 327 FrameMap::iterator info) { |
| 328 TRACE_EVENT0("webrtc", "FrameBuffer::UpdateFrameInfoWithIncomingFrame"); |
319 FrameKey key(frame.picture_id, frame.spatial_layer); | 329 FrameKey key(frame.picture_id, frame.spatial_layer); |
320 info->second.num_missing_continuous = frame.num_references; | 330 info->second.num_missing_continuous = frame.num_references; |
321 info->second.num_missing_decodable = frame.num_references; | 331 info->second.num_missing_decodable = frame.num_references; |
322 | 332 |
323 RTC_DCHECK(last_decoded_frame_it_ == frames_.end() || | 333 RTC_DCHECK(last_decoded_frame_it_ == frames_.end() || |
324 last_decoded_frame_it_->first < info->first); | 334 last_decoded_frame_it_->first < info->first); |
325 | 335 |
326 // Check how many dependencies that have already been fulfilled. | 336 // Check how many dependencies that have already been fulfilled. |
327 for (size_t i = 0; i < frame.num_references; ++i) { | 337 for (size_t i = 0; i < frame.num_references; ++i) { |
328 FrameKey ref_key(frame.references[i], frame.spatial_layer); | 338 FrameKey ref_key(frame.references[i], frame.spatial_layer); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 ref_info->second.num_missing_decodable); | 391 ref_info->second.num_missing_decodable); |
382 } | 392 } |
383 | 393 |
384 RTC_DCHECK_LE(info->second.num_missing_continuous, | 394 RTC_DCHECK_LE(info->second.num_missing_continuous, |
385 info->second.num_missing_decodable); | 395 info->second.num_missing_decodable); |
386 | 396 |
387 return true; | 397 return true; |
388 } | 398 } |
389 | 399 |
390 void FrameBuffer::UpdateJitterDelay() { | 400 void FrameBuffer::UpdateJitterDelay() { |
| 401 TRACE_EVENT0("webrtc", "FrameBuffer::UpdateJitterDelay"); |
391 if (!stats_callback_) | 402 if (!stats_callback_) |
392 return; | 403 return; |
393 | 404 |
394 int decode_ms; | 405 int decode_ms; |
395 int max_decode_ms; | 406 int max_decode_ms; |
396 int current_delay_ms; | 407 int current_delay_ms; |
397 int target_delay_ms; | 408 int target_delay_ms; |
398 int jitter_buffer_ms; | 409 int jitter_buffer_ms; |
399 int min_playout_delay_ms; | 410 int min_playout_delay_ms; |
400 int render_delay_ms; | 411 int render_delay_ms; |
401 if (timing_->GetTimings(&decode_ms, &max_decode_ms, ¤t_delay_ms, | 412 if (timing_->GetTimings(&decode_ms, &max_decode_ms, ¤t_delay_ms, |
402 &target_delay_ms, &jitter_buffer_ms, | 413 &target_delay_ms, &jitter_buffer_ms, |
403 &min_playout_delay_ms, &render_delay_ms)) { | 414 &min_playout_delay_ms, &render_delay_ms)) { |
404 stats_callback_->OnFrameBufferTimingsUpdated( | 415 stats_callback_->OnFrameBufferTimingsUpdated( |
405 decode_ms, max_decode_ms, current_delay_ms, target_delay_ms, | 416 decode_ms, max_decode_ms, current_delay_ms, target_delay_ms, |
406 jitter_buffer_ms, min_playout_delay_ms, render_delay_ms); | 417 jitter_buffer_ms, min_playout_delay_ms, render_delay_ms); |
407 } | 418 } |
408 } | 419 } |
409 | 420 |
410 void FrameBuffer::ClearFramesAndHistory() { | 421 void FrameBuffer::ClearFramesAndHistory() { |
| 422 TRACE_EVENT0("webrtc", "FrameBuffer::UpdateJitterDelay"); |
411 frames_.clear(); | 423 frames_.clear(); |
412 last_decoded_frame_it_ = frames_.end(); | 424 last_decoded_frame_it_ = frames_.end(); |
413 last_continuous_frame_it_ = frames_.end(); | 425 last_continuous_frame_it_ = frames_.end(); |
414 next_frame_it_ = frames_.end(); | 426 next_frame_it_ = frames_.end(); |
415 num_frames_history_ = 0; | 427 num_frames_history_ = 0; |
416 num_frames_buffered_ = 0; | 428 num_frames_buffered_ = 0; |
417 } | 429 } |
418 | 430 |
419 } // namespace video_coding | 431 } // namespace video_coding |
420 } // namespace webrtc | 432 } // namespace webrtc |
OLD | NEW |